summaryrefslogtreecommitdiff
path: root/ReferenceCode/AcpiTables/Cppc/Dxe
diff options
context:
space:
mode:
Diffstat (limited to 'ReferenceCode/AcpiTables/Cppc/Dxe')
-rw-r--r--ReferenceCode/AcpiTables/Cppc/Dxe/Cppc.c863
-rw-r--r--ReferenceCode/AcpiTables/Cppc/Dxe/Cppc.dxs35
-rw-r--r--ReferenceCode/AcpiTables/Cppc/Dxe/Cppc.h245
-rw-r--r--ReferenceCode/AcpiTables/Cppc/Dxe/Cppc.inf91
-rw-r--r--ReferenceCode/AcpiTables/Cppc/Dxe/CppcDxe.cif13
-rw-r--r--ReferenceCode/AcpiTables/Cppc/Dxe/CppcDxe.mak96
-rw-r--r--ReferenceCode/AcpiTables/Cppc/Dxe/CppcDxe.sdl30
7 files changed, 1373 insertions, 0 deletions
diff --git a/ReferenceCode/AcpiTables/Cppc/Dxe/Cppc.c b/ReferenceCode/AcpiTables/Cppc/Dxe/Cppc.c
new file mode 100644
index 0000000..9da9b1a
--- /dev/null
+++ b/ReferenceCode/AcpiTables/Cppc/Dxe/Cppc.c
@@ -0,0 +1,863 @@
+/** @file
+ This DXE driver configures and supports Collaborative Processor Performance Control (CPPC).
+
+@copyright
+ Copyright (c) 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
+
+**/
+#include "Cppc.h"
+
+ACPI_PLATFORM_POLICY_PROTOCOL *mAcpiPlatformPolicyProtocol;
+
+extern EFI_RUNTIME_SERVICES *gRT;
+extern EFI_BOOT_SERVICES *gBS;
+
+EFI_PHYSICAL_ADDRESS mCppcBaseAddressMem = 0;
+
+///
+/// Driver entry point
+///
+EFI_DRIVER_ENTRY_POINT (InitializeCppc)
+
+EFI_STATUS
+InitializeCppc (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/**
+@brief
+ Cppc DXE support.
+
+ @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 installed/initialized correctly.
+**/
+{
+ EFI_STATUS Status;
+ VOID *MemoryPointer;
+ UINT64 MsrValue;
+
+ gRT = SystemTable->RuntimeServices;
+ gBS = SystemTable->BootServices;
+
+ ///
+ /// Initialize the EFI Runtime Library
+ ///
+ DxeInitializeDriverLib (ImageHandle, SystemTable);
+
+ ///
+ /// S3 boot script
+ ///
+ INITIALIZE_SCRIPT (ImageHandle, SystemTable);
+
+ ///
+ /// Locate platform configuration information and copy it to a global variable.
+ ///
+ Status = gBS->LocateProtocol (
+ &gAcpiPlatformPolicyProtocolGuid,
+ NULL,
+ (VOID **) &mAcpiPlatformPolicyProtocol
+ );
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "CPPC: No Platform Policy Protocol available.\n"));
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ } else {
+ DEBUG ((EFI_D_ERROR, "CPPC: Platform Policy Protocol is loaded.\n"));
+ }
+
+ ///
+ /// Enable or disable CPPC depending on platform policy.
+ ///
+ if (mAcpiPlatformPolicyProtocol->EnableCppc == 0) {
+ DEBUG ((EFI_D_ERROR, "CPPC is disabled by platform policy. \n"));
+ return EFI_SUCCESS;
+ }
+
+ ///
+ /// Check if Haswell traditional, Haswell ULT or Crystal Well CPU.
+ ///
+ if(!(IsCpuSupported())){
+ DEBUG ((EFI_D_ERROR, "CPPC not supported in this CPU. \n"));
+ return EFI_SUCCESS;
+ }
+
+ ///
+ /// Check if Mobile CPU.
+ ///
+ if(!(IS_SA_DEVICE_ID_MOBILE (McD0PciCfg16 (R_SA_MC_DEVICE_ID)))) {
+ DEBUG ((EFI_D_ERROR, "CPPC not supported in this CPU. (not mobile) \n"));
+ return EFI_SUCCESS;
+ }
+
+ ///
+ /// Check if processor supports EE Policy capability.
+ ///
+ MsrValue = EfiReadMsr (EFI_MSR_POWER_CTL);
+ if (((UINT32)MsrValue & BIT18) != BIT18) {
+ DEBUG ((EFI_D_ERROR, "CPPC not supported in this CPU. (no Energy Efficient Policy capability) \n"));
+ return EFI_SUCCESS;
+ }
+
+ gST = SystemTable;
+ gDS = NULL;
+ Status = EfiGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID**) &gDS);
+
+ ///
+ /// Allocate 4kb of runtime memory.
+ ///
+ Status = (gBS->AllocatePool) (EfiACPIMemoryNVS, CPPC_SIZE, &MemoryPointer);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "CPPC: No Memory Buffer available.\n"));
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ } else {
+ mCppcBaseAddressMem = (EFI_PHYSICAL_ADDRESS) MemoryPointer;
+ ZeroMem ((VOID *)(UINTN)mCppcBaseAddressMem, CPPC_SIZE);
+ DEBUG((EFI_D_ERROR, "CPPC: PCCA memory buffer address: %x\n", mCppcBaseAddressMem));
+ }
+
+ ///
+ /// Add the Platform Communications Channel Table signature.
+ ///
+ CopyMem ((VOID *)(UINTN)mCppcBaseAddressMem, "PCC" , 3);
+
+ ///
+ /// Load the SSDT Table for the CPPC ACPI objects.
+ ///
+ LoadAcpiTables ();
+
+ ///
+ /// Load the ACPI 5.0 PCC Table.
+ ///
+ LoadAcpiTablesPcct ();
+
+ ///
+ /// Load the ACPI 5.0 _CPC objects.
+ ///
+ LoadAcpiTablesCpc ();
+
+ return EFI_SUCCESS;
+}
+
+VOID
+LoadAcpiTables(
+ VOID
+ )
+/**
+@brief
+ This procedure loads the CPPC SSDT table.
+
+ @param[in] None
+
+ @retval None
+
+**/
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN NumberOfHandles;
+ UINTN Index;
+ EFI_FIRMWARE_VOLUME_PROTOCOL *FwVol;
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
+ INTN Instance;
+ EFI_ACPI_COMMON_HEADER *Table;
+ UINTN Size;
+ EFI_FV_FILETYPE FileType;
+ EFI_FV_FILE_ATTRIBUTES Attributes;
+ UINT32 FvStatus;
+ EFI_ACPI_DESCRIPTION_HEADER *TableHeader;
+ UINTN TableHandle;
+ EFI_ACPI_TABLE_VERSION Version;
+ BOOLEAN LoadTable;
+ NAME_LAYOUT *NamePtr;
+ UINT8 *CurrPtr;
+ UINT32 *Signature;
+ UINT8 UpdateCounter;
+
+ FwVol = NULL;
+ Table = NULL;
+
+ ///
+ /// Locate FV protocol.
+ ///
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolumeProtocolGuid,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Look 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],
+ &gEfiFirmwareVolumeProtocolGuid,
+ (VOID **) &FwVol
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if ((Status == EFI_SUCCESS) && (FwVol != NULL)) {
+ ///
+ /// See if it has the ACPI storage file
+ ///
+ Size = 0;
+ FvStatus = 0;
+ Status = FwVol->ReadFile (
+ FwVol,
+ &gCppcAcpiTableStorageGuid,
+ NULL,
+ &Size,
+ &FileType,
+ &Attributes,
+ &FvStatus
+ );
+
+ ///
+ /// If we found it, then we are done
+ ///
+ if (Status == EFI_SUCCESS) {
+ break;
+ }
+ }
+ }
+
+ ///
+ /// Our exit status is determined by the success of the previous operations
+ /// If the protocol was found, Instance already points to it.
+ ///
+ /// Free any allocated buffers
+ ///
+ FreePool (HandleBuffer);
+
+ ///
+ /// Sanity check that we found our data file
+ ///
+ ASSERT (FwVol);
+ if (FwVol == NULL) {
+ return;
+ }
+
+ ///
+ /// By default, a table belongs in all ACPI table versions published.
+ ///
+ Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0;
+
+ ///
+ /// Find the Table protocol
+ ///
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
+
+ ///
+ /// Read tables from the storage file.
+ ///
+ Instance = 0;
+
+ while (Status == EFI_SUCCESS) {
+ ///
+ /// Read the ACPI tables
+ ///
+ Status = FwVol->ReadSection (
+ FwVol,
+ &gCppcAcpiTableStorageGuid,
+ EFI_SECTION_RAW,
+ Instance,
+ (VOID **) &Table,
+ &Size,
+ &FvStatus
+ );
+
+ if (!EFI_ERROR (Status)) {
+
+ LoadTable = FALSE;
+ TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
+
+ switch (((EFI_ACPI_DESCRIPTION_HEADER*) TableHeader)->OemTableId) {
+
+ case EFI_SIGNATURE_64 ('C', 'p', 'p', 'c', 'T', 'a', 'b', 'l'):
+ ///
+ /// This is Cppc SSDT. Cppc should be enabled if we reach here so load the table.
+ ///
+ LoadTable = TRUE;
+ DEBUG ((EFI_D_ERROR, "CPPC: Found Cppc SSDT signature.\n"));
+
+ UpdateCounter = 3; // Number of objects to initialize.
+ for (CurrPtr = (UINT8 *) TableHeader; ((CurrPtr <= ((UINT8 *) TableHeader + TableHeader->Length))) && UpdateCounter !=0; CurrPtr++) {
+ Signature = (UINT32 *) (CurrPtr + 1);
+ ///
+ /// Patch PCCA with the address of the CPPC shared memory buffer.
+ ///
+ if ((*CurrPtr == AML_NAME_OP) && (*Signature == EFI_SIGNATURE_32 ('P', 'C', 'C', 'A'))) {
+ NamePtr = (NAME_LAYOUT *) CurrPtr;
+ if (mCppcBaseAddressMem != 0){
+ NamePtr->Value = (UINT32) mCppcBaseAddressMem;
+ }
+ UpdateCounter--;
+ DEBUG((EFI_D_ERROR, "CPPC: PCCA pointer updated in SSDT: %x\n", mCppcBaseAddressMem));
+ }
+ ///
+ /// Patch PCCS with the size of the CPPC shared memory buffer.
+ ///
+ if ((*CurrPtr == AML_NAME_OP) && (*Signature == EFI_SIGNATURE_32 ('P', 'C', 'C', 'S'))) {
+ NamePtr = (NAME_LAYOUT *) CurrPtr;
+ NamePtr->Value = (UINT32) CPPC_SIZE;
+ UpdateCounter--;
+ DEBUG((EFI_D_ERROR, "CPPC: PCCS length updated in SSDT: %x\n", CPPC_SIZE));
+ }
+ ///
+ /// Patch PENB with the CPPC Enable/Disable Flag.
+ ///
+ if ((*CurrPtr == AML_NAME_OP) && (*Signature == EFI_SIGNATURE_32 ('P', 'E', 'N', 'B'))) {
+ NamePtr = (NAME_LAYOUT *) CurrPtr;
+ NamePtr->Value = (UINT32) mAcpiPlatformPolicyProtocol->EnableCppc;
+ UpdateCounter--;
+ DEBUG((EFI_D_ERROR, "CPPC: PENB updated in SSDT: %x\n", (UINT32) mAcpiPlatformPolicyProtocol->EnableCppc));
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ ///
+ /// Add the table
+ ///
+ if (LoadTable) {
+ TableHandle = 0;
+ Status = AcpiTable->InstallAcpiTable (
+ AcpiTable,
+ Table,
+ Table->Length,
+ &TableHandle
+ );
+ }
+
+ ///
+ /// Increment the instance
+ ///
+ Instance++;
+ Table = NULL;
+ }
+ }
+}
+
+VOID
+LoadAcpiTablesPcct(
+ VOID
+ )
+/**
+@brief
+ This procedure loads the ACPI 5.0 PCCT table.
+
+ @param[in] None
+
+ @retval None
+
+**/
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN NumberOfHandles;
+ UINTN Index;
+ EFI_FIRMWARE_VOLUME_PROTOCOL *FwVol;
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
+ INTN Instance;
+ EFI_ACPI_COMMON_HEADER *Table;
+ UINTN Size;
+ EFI_FV_FILETYPE FileType;
+ EFI_FV_FILE_ATTRIBUTES Attributes;
+ UINT32 FvStatus;
+ EFI_ACPI_DESCRIPTION_HEADER *TableHeader;
+ UINTN TableHandle;
+ EFI_ACPI_TABLE_VERSION Version;
+ BOOLEAN LoadTable;
+ EFI_ACPI_5_0_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER *PcctHeaderPtr;
+ EFI_ACPI_5_0_PCCT_SUBSPACE_GENERIC *PcctPtr;
+ UINT8 *CurrPtr;
+ UINT32 *Signature;
+ UINT8 UpdateCounter;
+
+ FwVol = NULL;
+ Table = NULL;
+
+ ///
+ /// Locate FV protocol.
+ ///
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolumeProtocolGuid,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Look 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],
+ &gEfiFirmwareVolumeProtocolGuid,
+ (VOID **) &FwVol
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if ((Status == EFI_SUCCESS) && (FwVol != NULL)) {
+ ///
+ /// See if it has the ACPI storage file
+ ///
+ Size = 0;
+ FvStatus = 0;
+ Status = FwVol->ReadFile (
+ FwVol,
+ &gCppcAcpiTableStorageGuid,
+ NULL,
+ &Size,
+ &FileType,
+ &Attributes,
+ &FvStatus
+ );
+
+ ///
+ /// If we found it, then we are done
+ ///
+ if (Status == EFI_SUCCESS) {
+ break;
+ }
+ }
+ }
+
+ ///
+ /// Our exit status is determined by the success of the previous operations
+ /// If the protocol was found, Instance already points to it.
+ ///
+ /// Free any allocated buffers
+ ///
+ FreePool (HandleBuffer);
+
+ ///
+ /// Sanity check that we found our data file
+ ///
+ ASSERT (FwVol);
+ if (FwVol == NULL) {
+ return;
+ }
+
+ ///
+ /// By default, a table belongs in all ACPI table versions published.
+ ///
+ Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0;
+
+ ///
+ /// Find the Table protocol
+ ///
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
+
+ ///
+ /// Read tables from the storage file.
+ ///
+ Instance = 0;
+
+ while (Status == EFI_SUCCESS) {
+ ///
+ /// Read the ACPI tables
+ ///
+ Status = FwVol->ReadSection (
+ FwVol,
+ &gCppcAcpiTableStorageGuid,
+ EFI_SECTION_RAW,
+ Instance,
+ (VOID **) &Table,
+ &Size,
+ &FvStatus
+ );
+
+ if (!EFI_ERROR (Status)) {
+
+ LoadTable = FALSE;
+ TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
+
+ switch (((EFI_ACPI_DESCRIPTION_HEADER*) TableHeader)->OemTableId) {
+
+ case EFI_SIGNATURE_64 ('P', 'c', 'c', 't', 'T', 'a', 'b', 'l'):
+ ///
+ /// This is PCCT. Cppc should be enabled if we reach here so load the table.
+ ///
+ LoadTable = TRUE;
+ DEBUG ((EFI_D_ERROR, "PCCT: Found PCCT signature.\n"));
+
+ UpdateCounter = 1; /// Number of objects to initialize.
+ for (CurrPtr = (UINT8 *) TableHeader; ((CurrPtr <= ((UINT8 *) TableHeader + TableHeader->Length))) && UpdateCounter !=0; CurrPtr++) {
+ Signature = (UINT32 *) (CurrPtr + 1);
+ ///
+ /// Patch the EFI_ACPI_5_0_PCCT_SUBSPACE_GENERIC structure.
+ ///
+ if ((*CurrPtr == AML_NAME_OP) && (*Signature == EFI_SIGNATURE_32 ('P', 'C', 'C', 'T'))) {
+ CurrPtr -= sizeof (EFI_ACPI_DESCRIPTION_HEADER); // backup the current pointer in order to use the PCCT header structure
+ PcctHeaderPtr = (EFI_ACPI_5_0_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER *) CurrPtr;
+ PcctHeaderPtr->Flags = (UINT32) mAcpiPlatformPolicyProtocol->EnableCppcPlatformSCI;
+ PcctHeaderPtr->Reserved = 0;
+
+ CurrPtr += sizeof (EFI_ACPI_5_0_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER);
+ PcctPtr = (EFI_ACPI_5_0_PCCT_SUBSPACE_GENERIC *) CurrPtr;
+ PcctPtr->Type = 0x0;
+ PcctPtr->Length = 62;
+ PcctPtr->BaseAddress = mCppcBaseAddressMem; /// Shared memory address
+ PcctPtr->AddressLength = CPPC_SIZE; /// sizeof(Shared memory) in bytes
+
+ PcctPtr->DoorbellRegister.AddressSpaceId = 1; /// IO address type
+ PcctPtr->DoorbellRegister.RegisterBitWidth = 8; /// byte
+ PcctPtr->DoorbellRegister.RegisterBitOffset = 0x0; /// offset=0
+ PcctPtr->DoorbellRegister.AccessSize = 1; /// byte access
+ PcctPtr->DoorbellRegister.Address = MmioRead16 (MmPciExpressAddress (0,0, PCI_DEV_NUM_ICH_LPC, 0, R_ACPI_BAR)) &~BIT0;
+ PcctPtr->DoorbellRegister.Address += R_ACPI_GPE_CNTL; /// PMBASE + GPE_CNTL register offset
+ PcctPtr->DoorbellPreserve = 0xFD; /// preserve all bits except bit 1
+ PcctPtr->DoorbellWrite = 2; /// write bit 1 = 1 to trigger GPE
+ PcctPtr->NominalLatency = 5000; /// 5ms
+ PcctPtr->MaximumPeriodicAccessRate = 0x0;
+ PcctPtr->MinimumRequestTurnaroundTime = 0x0;
+
+ UpdateCounter--;
+ DEBUG((EFI_D_ERROR, "PCCT: Patch the EFI_ACPI_5_0_PCCT_SUBSPACE_GENERIC structure.\n"));
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ ///
+ /// Add the table
+ ///
+ if (LoadTable) {
+ TableHandle = 0;
+ Status = AcpiTable->InstallAcpiTable (
+ AcpiTable,
+ Table,
+ Table->Length,
+ &TableHandle
+ );
+ }
+
+ ///
+ /// Increment the instance
+ ///
+ Instance++;
+ Table = NULL;
+ }
+ }
+}
+
+VOID
+LoadAcpiTablesCpc(
+ VOID
+ )
+/**
+@brief
+ Load ACPI SSDT tables.
+
+ @param[in] None
+
+ @retval None
+
+**/
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN NumberOfHandles;
+ UINTN Index;
+ EFI_FIRMWARE_VOLUME_PROTOCOL *FwVol;
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
+ INTN Instance;
+ EFI_ACPI_COMMON_HEADER *Table;
+ UINTN Size;
+ EFI_FV_FILETYPE FileType;
+ EFI_FV_FILE_ATTRIBUTES Attributes;
+ UINT32 FvStatus;
+ EFI_ACPI_DESCRIPTION_HEADER *TableHeader;
+ UINTN TableHandle;
+ EFI_ACPI_TABLE_VERSION Version;
+ BOOLEAN LoadTable;
+
+ FwVol = NULL;
+ Table = NULL;
+
+ ///
+ /// Locate FV protocol.
+ ///
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolumeProtocolGuid,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Look 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],
+ &gEfiFirmwareVolumeProtocolGuid,
+ (VOID **) &FwVol
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if ((Status == EFI_SUCCESS) && (FwVol != NULL)) {
+ ///
+ /// See if it has the ACPI storage file
+ ///
+ Size = 0;
+ FvStatus = 0;
+ Status = FwVol->ReadFile (
+ FwVol,
+ &gCppcAcpiTableStorageGuid,
+ NULL,
+ &Size,
+ &FileType,
+ &Attributes,
+ &FvStatus
+ );
+
+ ///
+ /// If we found it, then we are done
+ ///
+ if (Status == EFI_SUCCESS) {
+ break;
+ }
+ }
+ }
+
+ ///
+ /// Our exit status is determined by the success of the previous operations
+ /// If the protocol was found, Instance already points to it.
+ ///
+ /// Free any allocated buffers
+ ///
+ FreePool (HandleBuffer);
+
+ ///
+ /// Sanity check that we found our data file
+ ///
+ ASSERT (FwVol);
+ if (FwVol == NULL) {
+ return;
+ }
+
+ ///
+ /// By default, a table belongs in all ACPI table versions published.
+ ///
+ Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0;
+
+ ///
+ /// Find the Table protocol
+ ///
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
+
+ ///
+ /// Read tables from the storage file.
+ ///
+ Instance = 0;
+
+ while (Status == EFI_SUCCESS) {
+ ///
+ /// Read the ACPI tables
+ ///
+ Status = FwVol->ReadSection (
+ FwVol,
+ &gCppcAcpiTableStorageGuid,
+ EFI_SECTION_RAW,
+ Instance,
+ (VOID **) &Table,
+ &Size,
+ &FvStatus
+ );
+
+ if (!EFI_ERROR (Status)) {
+
+ LoadTable = FALSE;
+ TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
+
+ switch (((EFI_ACPI_DESCRIPTION_HEADER*) TableHeader)->OemTableId) {
+
+ case EFI_SIGNATURE_64 ('C', 'p', 'c', '_', 'T', 'a', 'b', 'l'):
+ ///
+ /// This is the _CPC SSDT. Cppc should be enabled if we reach here so load the table.
+ ///
+ LoadTable = TRUE;
+ DEBUG ((EFI_D_ERROR, "CPPC: Found _CPC SSDT signature.\n"));
+ break;
+
+ default:
+ break;
+ }
+
+ ///
+ /// Add the table
+ ///
+ if (LoadTable) {
+ TableHandle = 0;
+ Status = AcpiTable->InstallAcpiTable (
+ AcpiTable,
+ Table,
+ Table->Length,
+ &TableHandle
+ );
+ }
+
+ ///
+ /// Increment the instance
+ ///
+ Instance++;
+ Table = NULL;
+ }
+ }
+}
+
+EFI_STATUS
+LocateSupportProtocol (
+ IN EFI_GUID *Protocol,
+ OUT VOID **Instance,
+ IN BOOLEAN Type
+ )
+/**
+ @brief
+ 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] The protocol to find.
+ @param[in] Return pointer to the first instance of the protocol
+ @param[in] TRUE if the desired protocol is a FV protocol
+
+ @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 Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN NumberOfHandles;
+ EFI_FV_FILETYPE FileType;
+ UINT32 FvStatus;
+ EFI_FV_FILE_ATTRIBUTES Attributes;
+ UINTN Size;
+ UINTN i;
+
+ ///
+ /// Locate protocol.
+ ///
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ Protocol,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+
+ ///
+ /// Defined errors at this time are not found and out of resources.
+ ///
+ return Status;
+ }
+
+ ///
+ /// Looking for FV with ACPI storage file
+ ///
+ for (i = 0; i < NumberOfHandles; i++) {
+
+ ///
+ /// Get the protocol on this handle
+ /// This should not fail because of LocateHandleBuffer
+ ///
+ Status = gBS->HandleProtocol (
+ HandleBuffer[i],
+ Protocol,
+ Instance
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (!Type) {
+
+ ///
+ /// Not looking for the FV protocol, so find the first instance of the
+ /// protocol. There should not be any errors because our handle buffer
+ /// should always contain at least one or LocateHandleBuffer would have
+ /// returned not found.
+ ///
+ break;
+ }
+
+ ///
+ /// See if it has the ACPI storage file
+ ///
+ Size = 0;
+ FvStatus = 0;
+ Status = ((EFI_FIRMWARE_VOLUME_PROTOCOL *) (*Instance))->ReadFile (
+ *Instance,
+ &gCppcAcpiTableStorageGuid,
+ NULL,
+ &Size,
+ &FileType,
+ &Attributes,
+ &FvStatus
+ );
+
+ ///
+ /// If we found it, then we are done
+ ///
+ if (Status == EFI_SUCCESS) {
+ break;
+ }
+ }
+
+ ///
+ /// Our exit status is determined by the success of the previous operations
+ /// If the protocol was found, Instance already points to it.
+ ///
+ /// Free any allocated buffers
+ ///
+ FreePool (HandleBuffer);
+
+ return Status;
+}
diff --git a/ReferenceCode/AcpiTables/Cppc/Dxe/Cppc.dxs b/ReferenceCode/AcpiTables/Cppc/Dxe/Cppc.dxs
new file mode 100644
index 0000000..d1df44e
--- /dev/null
+++ b/ReferenceCode/AcpiTables/Cppc/Dxe/Cppc.dxs
@@ -0,0 +1,35 @@
+/** @file
+ Dependency expression source file.
+
+@copyright
+ Copyright (c) 1999 - 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
+
+**/
+
+
+#include "EfiDepex.h"
+#include EFI_PROTOCOL_DEPENDENCY (CpuIo)
+#include EFI_PROTOCOL_DEPENDENCY (AcpiSupport)
+#include EFI_PROTOCOL_DEPENDENCY (AcpiPlatformPolicy)
+#include EFI_PROTOCOL_DEPENDENCY (PowerMgmtInitDone)
+
+DEPENDENCY_START
+ EFI_CPU_IO_PROTOCOL_GUID AND
+ EFI_ACPI_SUPPORT_GUID AND
+ ACPI_PLATFORM_POLICY_PROTOCOL_GUID AND
+ EFI_POWER_MGMT_INIT_DONE_PROTOCOL_GUID
+DEPENDENCY_END
diff --git a/ReferenceCode/AcpiTables/Cppc/Dxe/Cppc.h b/ReferenceCode/AcpiTables/Cppc/Dxe/Cppc.h
new file mode 100644
index 0000000..289fe93
--- /dev/null
+++ b/ReferenceCode/AcpiTables/Cppc/Dxe/Cppc.h
@@ -0,0 +1,245 @@
+/** @file
+ Header file for the Collaborative Processor Performance Control (CPPC) driver.
+
+@copyright
+ Copyright (c) 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 _CPPC_H_
+#define _CPPC_H_
+
+#include "EdkIIGlueBase.h"
+#include "EdkIIGlueDxe.h"
+#include "EfiScriptLib.h"
+#include "Acpi.h"
+#include "SaAccess.h"
+#include "CpuAccess.h"
+#include "CpuPlatformLib.h"
+///
+/// Consumed protocols
+///
+#include EFI_PROTOCOL_DEPENDENCY (AcpiTable)
+#include EFI_PROTOCOL_DEPENDENCY (FirmwareVolume)
+#include EFI_PROTOCOL_CONSUMER (PciRootBridgeIo)
+#include EFI_PROTOCOL_DEFINITION (AcpiPlatformPolicy)
+
+#define CPPC_SIZE 0x1000 /// 4kb of runtime memory for CPPC shared memory buffer
+#define PCI_DEV_NUM_ICH_LPC 31 /// ICH is Device 31
+#define R_ACPI_BAR 0x40 /// ACPI Base Address Register
+#define R_ACPI_GPE_CNTL 0x42 /// GPE control register offset
+#define CPUID_FULL_FAMILY_MODEL_HASWELL 0x000306C0
+#define EFI_MSR_POWER_CTL 0x000001FC
+
+///
+/// SSDT data storage file
+///
+#include "CppcAcpiTableStorage.h"
+
+///
+/// AML parsing definitions
+///
+#define AML_NAME_OP 0x08
+
+///
+/// ASL NAME structure
+///
+#pragma pack(1)
+typedef struct {
+ UINT8 NameOp; // Byte [0]=0x08:NameOp.
+ UINT32 NameString; // Byte [4:1]=Name of object.
+ UINT8 DWordPrefix; // Byte [5]=0x0C:DWord Prefix.
+ UINT32 Value; // Byte [9:6] ; Value of named object.
+} NAME_LAYOUT;
+#pragma pack()
+
+///
+/// ACPI 5.0 Generic Address Space definition
+///
+#pragma pack(1)
+typedef struct {
+ UINT8 AddressSpaceId;
+ UINT8 RegisterBitWidth;
+ UINT8 RegisterBitOffset;
+ UINT8 AccessSize;
+ UINT64 Address;
+} EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE;
+#pragma pack()
+
+///
+/// Platform Communications Channel Table (PCCT)
+///
+#pragma pack(1)
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT32 Flags;
+ UINT64 Reserved;
+} EFI_ACPI_5_0_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER;
+#pragma pack()
+
+///
+/// Generic Communications Subspace Structure
+///
+#pragma pack(1)
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 Reserved[6];
+ UINT64 BaseAddress;
+ UINT64 AddressLength;
+ EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE DoorbellRegister;
+ UINT64 DoorbellPreserve;
+ UINT64 DoorbellWrite;
+ UINT32 NominalLatency;
+ UINT32 MaximumPeriodicAccessRate;
+ UINT16 MinimumRequestTurnaroundTime;
+} EFI_ACPI_5_0_PCCT_SUBSPACE_GENERIC;
+#pragma pack()
+
+///
+/// UINT64 workaround
+///
+/// The MS compiler doesn't handle QWORDs very well. I'm breaking
+/// them into DWORDs to circumvent the problems. Converting back
+/// shouldn't be a big deal.
+///
+#pragma pack(1)
+typedef union _MSR_REGISTER {
+ UINT64 Qword;
+
+ struct _DWORDS {
+ UINT32 Low;
+ UINT32 High;
+ } Dwords;
+
+ struct _BYTES {
+ UINT8 FirstByte;
+ UINT8 SecondByte;
+ UINT8 ThirdByte;
+ UINT8 FouthByte;
+ UINT8 FifthByte;
+ UINT8 SixthByte;
+ UINT8 SeventhByte;
+ UINT8 EighthByte;
+ } Bytes;
+
+} MSR_REGISTER;
+#pragma pack()
+
+#ifndef BIT63
+#define BIT0 0x0001
+#define BIT1 0x0002
+#define BIT2 0x0004
+#define BIT3 0x0008
+#define BIT4 0x0010
+#define BIT5 0x0020
+#define BIT6 0x0040
+#define BIT7 0x0080
+#define BIT8 0x0100
+#define BIT9 0x0200
+#define BIT10 0x0400
+#define BIT11 0x0800
+#define BIT12 0x1000
+#define BIT13 0x2000
+#define BIT14 0x4000
+#define BIT15 0x8000
+#define BIT16 0x00010000
+#define BIT17 0x00020000
+#define BIT18 0x00040000
+#define BIT19 0x00080000
+#define BIT20 0x00100000
+#define BIT21 0x00200000
+#define BIT22 0x00400000
+#define BIT23 0x00800000
+#define BIT24 0x01000000
+#define BIT25 0x02000000
+#define BIT26 0x04000000
+#define BIT27 0x08000000
+#define BIT28 0x10000000
+#define BIT29 0x20000000
+#define BIT30 0x40000000
+#define BIT31 0x80000000
+#define BIT32 0x100000000
+#define BIT33 0x200000000
+#define BIT34 0x400000000
+#define BIT35 0x800000000
+#define BIT36 0x1000000000
+#define BIT37 0x2000000000
+#define BIT38 0x4000000000
+#define BIT39 0x8000000000
+#define BIT40 0x10000000000
+#define BIT41 0x20000000000
+#define BIT42 0x40000000000
+#define BIT43 0x80000000000
+#define BIT44 0x100000000000
+#define BIT45 0x200000000000
+#define BIT46 0x400000000000
+#define BIT47 0x800000000000
+#define BIT48 0x1000000000000
+#define BIT49 0x2000000000000
+#define BIT50 0x4000000000000
+#define BIT51 0x8000000000000
+#define BIT52 0x10000000000000
+#define BIT53 0x20000000000000
+#define BIT54 0x40000000000000
+#define BIT55 0x80000000000000
+#define BIT56 0x100000000000000
+#define BIT57 0x200000000000000
+#define BIT58 0x400000000000000
+#define BIT59 0x800000000000000
+#define BIT60 0x1000000000000000
+#define BIT61 0x2000000000000000
+#define BIT62 0x4000000000000000
+#define BIT63 0x8000000000000000
+#endif
+
+#define MmPciExpressAddress(Segment, Bus, Device, Function, Register) \
+ ( (UINTN) (PciRead32 (PCI_LIB_ADDRESS (0,0,0,0x60)) & 0xFC000000) + \
+ (UINTN) (Bus << 20) + \
+ (UINTN) (Device << 15) + \
+ (UINTN) (Function << 12) + \
+ (UINTN) (Register) \
+ )
+
+EFI_STATUS
+InitializeCppc (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+VOID
+LoadAcpiTables(
+ VOID
+ );
+
+VOID
+LoadAcpiTablesPcct(
+ VOID
+ );
+
+VOID
+LoadAcpiTablesCpc(
+ VOID
+ );
+
+EFI_STATUS
+LocateSupportProtocol (
+ IN EFI_GUID *Protocol,
+ OUT VOID **Instance,
+ IN BOOLEAN Type
+ );
+
+#endif
diff --git a/ReferenceCode/AcpiTables/Cppc/Dxe/Cppc.inf b/ReferenceCode/AcpiTables/Cppc/Dxe/Cppc.inf
new file mode 100644
index 0000000..731cf82
--- /dev/null
+++ b/ReferenceCode/AcpiTables/Cppc/Dxe/Cppc.inf
@@ -0,0 +1,91 @@
+## @file
+# Component description file for Cppc module
+#
+#@copyright
+# Copyright (c) 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
+#
+
+
+[defines]
+BASE_NAME = Cppc
+FILE_GUID = C07A1EB5-5C04-4100-817B-0A11BB5F15DC
+COMPONENT_TYPE = RT_DRIVER
+
+[sources.common]
+ Cppc.h
+ Cppc.c
+
+[includes.common]
+ $(EFI_SOURCE)/$(PROJECT_ACPI_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_ACPI_ROOT)/Cppc
+ $(EFI_SOURCE)/$(PROJECT_ACPI_ROOT)/Cppc/Guid/AcpiTableStorage
+ .
+ $(EDK_SOURCE)/Sample/Chipset/PcCompatible
+ $(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)/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Core/Dxe
+ $(EDK_SOURCE)/Foundation/Core/Dxe/ArchProtocol/Cpu
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EFI_SOURCE)
+ $(EFI_SOURCE)/Framework
+ $(EFI_SOURCE)/Include
+ $(EFI_SOURCE)/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include/Pcd
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include/Library
+ $(EDK_SOURCE)/Foundation/Cpu/Pentium/Include
+ $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/Include/Library
+ $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/Library/CpuPlatformLib
+ $(EFI_SOURCE)/$(PROJECT_SA_ROOT)/Include
+
+[libraries.common]
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkIIGlueBaseLib
+ EdkIIGlueDxeReportStatusCodeLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkProtocolLib
+ EfiProtocolLib
+ EfiDriverLib
+ ArchProtocolLib
+ EdkFrameworkProtocolLib
+ EdkIIGlueBasePciExpressLib
+ EdkIIGlueUefiLib
+ EfiScriptLib
+ AcpiProtocolLib
+ CpuProtocolLib
+ CpuPlatformLib
+ CppcGuidLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = InitializeCppc
+ DPX_SOURCE = Cppc.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializeCppc" \
+ -D __EDKII_GLUE_BASE_LIB__ \
+ -D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__
+
diff --git a/ReferenceCode/AcpiTables/Cppc/Dxe/CppcDxe.cif b/ReferenceCode/AcpiTables/Cppc/Dxe/CppcDxe.cif
new file mode 100644
index 0000000..5379e0e
--- /dev/null
+++ b/ReferenceCode/AcpiTables/Cppc/Dxe/CppcDxe.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "CppcDxe"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\AcpiTables\Cppc\Dxe\"
+ RefName = "CppcDxe"
+[files]
+"CppcDxe.sdl"
+"CppcDxe.mak"
+"Cppc.c"
+"Cppc.dxs"
+"Cppc.h"
+"Cppc.inf"
+<endComponent>
diff --git a/ReferenceCode/AcpiTables/Cppc/Dxe/CppcDxe.mak b/ReferenceCode/AcpiTables/Cppc/Dxe/CppcDxe.mak
new file mode 100644
index 0000000..a318f31
--- /dev/null
+++ b/ReferenceCode/AcpiTables/Cppc/Dxe/CppcDxe.mak
@@ -0,0 +1,96 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: CppcDxe.mak
+#
+# Description: Make file to build Intel CPPC components
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+EDK : CppcDxe
+
+CppcDxe : $(BUILD_DIR)\CppcDxe.mak CppcDxeBin
+
+CppcDxe_OBJECTS = \
+$(BUILD_DIR)\$(INTEL_CPPC_DXE_DIR)\Cppc.obj
+
+$(BUILD_DIR)\CppcDxe.mak : $(INTEL_CPPC_DXE_DIR)\$(@B).cif $(INTEL_CPPC_DXE_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(INTEL_CPPC_DXE_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+CppcDxe_LIBS =\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(EDKPROTOCOLLIB)\
+ $(EFIPROTOCOLLIB)\
+ $(ARCHPROTOCOLLIB)\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(EFISCRIPTLIB)\
+ $(EdkIIGlueBaseLib_LIB)\
+ $(EdkIIGlueBasePciExpressLib_LIB)\
+ $(EdkIIGlueUefiLib_LIB)\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueDxeServicesTableLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueDxeHobLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(EFIDRIVERLIB)\
+ $(AcpiProtocolLib_LIB)\
+ $(CppcGuidLib_LIB)\
+ $(CpuProtocolLib_LIB)\
+ $(CpuPlatformLib_LIB)\
+ $(PchPlatformDxeLib_LIB)\
+
+CppcDxe_INCLUDES= $(EDK_INCLUDES)\
+ $(IndustryStandard_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(CPPC_INCLUDES)\
+ /I ReferenceCode\AcpiTables\
+ /I$(ArchProtocolLib_DIR)\Cpu\
+ $(PROJECT_CPU_INCLUDES)\
+ /I$(PROJECT_CPU_ROOT)\Library\CpuPlatformLib\
+ /I$(INTEL_SYSTEM_AGENT_DIR)\Include\
+
+CppcDxeBin: $(CppcDxe_LIBS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\CppcDxe.mak all \
+ NAME=CppcDxe\
+ MAKEFILE=$(BUILD_DIR)\CppcDxe.mak \
+ "MY_INCLUDES=$(CppcDxe_INCLUDES)"\
+ GUID=C07A1EB5-5C04-4100-817B-0A11BB5F15DC\
+ ENTRY_POINT=InitializeCppc \
+ TYPE=RT_DRIVER\
+ "OBJECTS=$(CppcDxe_OBJECTS)"\
+ DEPEX1=$(INTEL_CPPC_DXE_DIR)\Cppc.dxs\
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX\
+ COMPRESS=1
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#************************************************************************* \ No newline at end of file
diff --git a/ReferenceCode/AcpiTables/Cppc/Dxe/CppcDxe.sdl b/ReferenceCode/AcpiTables/Cppc/Dxe/CppcDxe.sdl
new file mode 100644
index 0000000..164ab26
--- /dev/null
+++ b/ReferenceCode/AcpiTables/Cppc/Dxe/CppcDxe.sdl
@@ -0,0 +1,30 @@
+TOKEN
+ Name = "CppcDxe_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable CppcDxe support in Project"
+End
+
+MODULE
+ Help = "Includes CppcDxe.mak to Project"
+ File = "CppcDxe.mak"
+End
+
+PATH
+ Name = "INTEL_CPPC_DXE_DIR"
+End
+
+ELINK
+ Name = "/I$(INTEL_CPPC_DXE_DIR)"
+ Parent = "CPPC_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CppcDxe.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End