534 lines
18 KiB
C
534 lines
18 KiB
C
/** @file
|
|
This file contains Processor Power Management ACPI related functions for
|
|
processors.
|
|
|
|
<b>Acronyms:</b>
|
|
- PPM: Processor Power Management
|
|
- TM: Thermal Monitor
|
|
- IST: Intel(R) Speedstep technology
|
|
- HT: Hyper-Threading Technology
|
|
- ITBM: Intel(R) Turbo Boost Max Technology 3.0
|
|
|
|
@copyright
|
|
INTEL CONFIDENTIAL
|
|
Copyright 2012 - 2020 Intel Corporation.
|
|
|
|
The source code contained or described herein and all documents related to the
|
|
source code ("Material") are owned by Intel Corporation or its suppliers or
|
|
licensors. Title to the Material remains with Intel Corporation or its suppliers
|
|
and licensors. The Material may contain trade secrets and proprietary and
|
|
confidential information of Intel Corporation and its suppliers and licensors,
|
|
and is protected by worldwide copyright and trade secret laws and treaty
|
|
provisions. No part of the Material may be used, copied, reproduced, modified,
|
|
published, uploaded, posted, transmitted, distributed, or disclosed in any way
|
|
without Intel's prior express written permission.
|
|
|
|
No license under any patent, copyright, trade secret or other intellectual
|
|
property right is granted to or conferred upon you by disclosure or delivery
|
|
of the Materials, either expressly, by implication, inducement, estoppel or
|
|
otherwise. Any license under such intellectual property rights must be
|
|
express and approved by Intel in writing.
|
|
|
|
Unless otherwise agreed by Intel in writing, you may not remove or alter
|
|
this notice or any other notice embedded in Materials by Intel or
|
|
Intel's suppliers or licensors in any way.
|
|
|
|
This file contains an 'Intel Peripheral Driver' and is 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.
|
|
|
|
@par Specification Reference:
|
|
**/
|
|
|
|
#include "PowerMgmtInit.h"
|
|
#if FixedPcdGetBool(PcdBiosGuardEnable) == 1
|
|
#include <Protocol/BiosGuardNvsArea.h>
|
|
#endif
|
|
|
|
|
|
/**
|
|
This will perform Miscellaneous Power Management related programming.
|
|
**/
|
|
VOID
|
|
InitMiscFeatures (
|
|
VOID
|
|
)
|
|
{
|
|
}
|
|
|
|
/**
|
|
Update the SSDT table pointers and config DWORD CFGD with the PpmFlags current configuration value
|
|
**/
|
|
VOID
|
|
PatchCpuSsdtTable (
|
|
VOID
|
|
)
|
|
{
|
|
UINT8 *CurrPtr;
|
|
UINT32 *Signature;
|
|
SSDT_LAYOUT *SsdtPackage;
|
|
#if FixedPcdGetBool(PcdBiosGuardEnable) == 1
|
|
BIOSGUARD_NVS_AREA_PROTOCOL *BiosGuardNvsAreaProtocol = NULL;
|
|
EFI_STATUS Status;
|
|
#endif
|
|
BOOLEAN BiosGuardEnable;
|
|
BOOLEAN BiosGuardReady;
|
|
|
|
///
|
|
/// Locate the SSDT package
|
|
///
|
|
SsdtPackage = NULL;
|
|
CurrPtr = (UINT8 *) mCpuSsdtTable;
|
|
BiosGuardEnable = FALSE;
|
|
BiosGuardReady = FALSE;
|
|
|
|
#if FixedPcdGetBool(PcdBiosGuardEnable) == 1
|
|
BiosGuardEnable = IsBiosGuardEnabled ();
|
|
///
|
|
/// Locate BIOS Guard NVS if BIOS Guard is Enabled
|
|
///
|
|
if (BiosGuardEnable == TRUE) {
|
|
DEBUG ((DEBUG_INFO, "\n BIOS Guard is Enabled\n"));
|
|
Status = gBS->LocateProtocol (&gBiosGuardNvsAreaProtocolGuid, NULL, (VOID **) &BiosGuardNvsAreaProtocol);
|
|
if ((!EFI_ERROR (Status)) && BiosGuardNvsAreaProtocol != NULL ) {
|
|
BiosGuardReady = TRUE;
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "\n Unable to Locate BIOS Guard Protocol\n"));
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "\n BIOS Guard is Disabled\n"));
|
|
}
|
|
#endif
|
|
|
|
for (CurrPtr = (UINT8 *) mCpuSsdtTable; CurrPtr <= ((UINT8 *) mCpuSsdtTable + mCpuSsdtTable->Length); CurrPtr++) {
|
|
Signature = (UINT32 *) (CurrPtr + 1);
|
|
if ((*CurrPtr == AML_NAME_OP) && *Signature == SIGNATURE_32 ('S', 'S', 'D', 'T')) {
|
|
///
|
|
/// Update the SSDT table pointers for dynamically loaded tables
|
|
///
|
|
SsdtPackage = (SSDT_LAYOUT *) CurrPtr;
|
|
///
|
|
/// Set the P-State SSDT table information
|
|
///
|
|
SsdtPackage->Cpu0IstAddr = (UINT32) (UINTN) mCpu0IstTable;
|
|
SsdtPackage->Cpu0IstLen = mCpu0IstTable->Length;
|
|
SsdtPackage->ApIstAddr = (UINT32) (UINTN) mApIstTable;
|
|
SsdtPackage->ApIstLen = mApIstTable->Length;
|
|
///
|
|
/// Set the C-State SSDT table information
|
|
///
|
|
SsdtPackage->Cpu0CstAddr = (UINT32) (UINTN) mCpu0CstTable;
|
|
SsdtPackage->Cpu0CstLen = mCpu0CstTable->Length;
|
|
SsdtPackage->ApCstAddr = (UINT32) (UINTN) mApCstTable;
|
|
SsdtPackage->ApCstLen = mApCstTable->Length;
|
|
///
|
|
/// Save Cpu0Hwp and Ap0Hwp address to load SSDT Dynamically in ASL
|
|
///
|
|
if (mCpu0HwpTable != NULL) {
|
|
SsdtPackage->Cpu0HwpAddr = (UINT32) (UINTN) mCpu0HwpTable;
|
|
SsdtPackage->Cpu0HwpLen = mCpu0HwpTable->Length;
|
|
if (mApHwpTable != NULL) {
|
|
SsdtPackage->ApHwpAddr = (UINT32) (UINTN) mApHwpTable;
|
|
SsdtPackage->ApHwpLen = mApHwpTable->Length;
|
|
}
|
|
}
|
|
///
|
|
/// Set the P-State PSD SSDT table information
|
|
///
|
|
SsdtPackage->Cpu0PsdAddr = (UINT32) (UINTN) mCpu0PsdTable;
|
|
SsdtPackage->Cpu0PsdLen = mCpu0PsdTable->Length;
|
|
SsdtPackage->ApPsdAddr = (UINT32) (UINTN) mApPsdTable;
|
|
SsdtPackage->ApPsdLen = mApPsdTable->Length;
|
|
DEBUG ((DEBUG_INFO, "\n Cpu0Ist :%x :%x \n",SsdtPackage->Cpu0IstAddr,SsdtPackage->Cpu0IstLen));
|
|
DEBUG ((DEBUG_INFO, "\n Cpu0Cst :%x :%x \n",SsdtPackage->Cpu0CstAddr,SsdtPackage->Cpu0CstLen));
|
|
DEBUG ((DEBUG_INFO, "\n Cpu0Hwp :%x :%x \n",SsdtPackage->Cpu0HwpAddr,SsdtPackage->Cpu0HwpLen));
|
|
DEBUG ((DEBUG_INFO, "\n ApHwp :%x :%x \n",SsdtPackage->ApHwpAddr,SsdtPackage->ApHwpLen));
|
|
DEBUG ((DEBUG_INFO, "\n Cpu0Psd :%x :%x \n",SsdtPackage->Cpu0PsdAddr,SsdtPackage->Cpu0PsdLen));
|
|
DEBUG ((DEBUG_INFO, "\n ApPsdAddr :%x :%x \n",SsdtPackage->ApPsdAddr,SsdtPackage->ApPsdLen));
|
|
}
|
|
///
|
|
/// Update the CPU GlobalNvs area
|
|
///
|
|
if ((*CurrPtr == AML_EXT_REGION_OP) && *Signature == SIGNATURE_32 ('P', 'N', 'V', 'S')) {
|
|
ASSERT (*(UINT32 *) (CurrPtr + 1 + sizeof (*Signature) + 2) == 0xFFFF0000);
|
|
ASSERT (*(UINT16 *) (CurrPtr + 1 + sizeof (*Signature) + 2 + sizeof (UINT32) + 1) == 0xAA55);
|
|
///
|
|
/// Cpu Nvs Area address
|
|
///
|
|
*(UINT32 *) (CurrPtr + 1 + sizeof (*Signature) + 2) = (UINT32) (UINTN) gCpuNvsAreaProtocol->Area;
|
|
///
|
|
/// Cpu Nvs Area size
|
|
///
|
|
*(UINT16 *) (CurrPtr + 1 + sizeof (*Signature) + 2 + sizeof (UINT32) + 1) = sizeof (CPU_NVS_AREA);
|
|
#if FixedPcdGetBool(PcdBiosGuardEnable) == 0
|
|
break;
|
|
#endif
|
|
}
|
|
|
|
#if FixedPcdGetBool(PcdBiosGuardEnable) == 1
|
|
///
|
|
/// Update the BIOS Guard NVS area if BIOS Guard is Enabled and Ready
|
|
///
|
|
if ((BiosGuardEnable == TRUE) &&
|
|
(BiosGuardReady == TRUE) &&
|
|
(*CurrPtr == AML_EXT_REGION_OP) &&
|
|
(*Signature == SIGNATURE_32 ('B', 'G', 'N', 'V'))) {
|
|
ASSERT (*(UINT32 *) (CurrPtr + 1 + sizeof (*Signature) + 2) == 0xFFFF0000);
|
|
ASSERT (*(UINT16 *) (CurrPtr + 1 + sizeof (*Signature) + 2 + sizeof (UINT32) + 1) == 0xAA55);
|
|
///
|
|
/// BIOS Guard Nvs Area address
|
|
///
|
|
*(UINT32 *) (CurrPtr + 1 + sizeof (*Signature) + 2) = (UINT32) (UINTN) gBiosGuardNvsAreaProtocol->Area;
|
|
///
|
|
/// BIOS Guard Nvs Area size
|
|
///
|
|
*(UINT16 *) (CurrPtr + 1 + sizeof (*Signature) + 2 + sizeof (UINT32) + 1) = sizeof (BIOSGUARD_NVS_AREA);
|
|
break;
|
|
}
|
|
|
|
#endif
|
|
}
|
|
//
|
|
// Assert if we didn't update the SSDT table
|
|
//
|
|
ASSERT (SsdtPackage != NULL);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
This function relocalte a reserved pool for CPU ssdt table and recalculate the checksum.
|
|
|
|
@param[in,out] **AcpiDescHeader A point to CPU SSDT point.
|
|
|
|
@retval EFI_INVALID_PARAMETER Invalid input.
|
|
EFI_OUT_OF_RESOURCES Allocate buffer fails.
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
RelocateAndUpdateCpuSsdtChecksum (
|
|
EFI_ACPI_DESCRIPTION_HEADER **AcpiDescHeader
|
|
)
|
|
{
|
|
EFI_ACPI_DESCRIPTION_HEADER *TempTable;
|
|
|
|
if ((AcpiDescHeader == NULL) || (*AcpiDescHeader == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
TempTable = AllocateReservedPool ((*AcpiDescHeader)->Length);
|
|
if (TempTable == NULL) {
|
|
ASSERT (TempTable != NULL);
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
CopyMem (TempTable, *AcpiDescHeader, (*AcpiDescHeader)->Length);
|
|
FreePool (*AcpiDescHeader);
|
|
*AcpiDescHeader = TempTable;
|
|
(*AcpiDescHeader)->Checksum = 0;
|
|
(*AcpiDescHeader)->Checksum = CalculateCheckSum8 ((CONST UINT8 *) *AcpiDescHeader, (*AcpiDescHeader)->Length);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Locate the PPM ACPI tables data file and read ACPI SSDT tables.
|
|
Publish the appropriate SSDT based on current configuration and capabilities.
|
|
|
|
@retval EFI_SUCCESS - On success
|
|
@retval EFI_NOT_FOUND - Required firmware volume not found
|
|
@retval EFI_OUT_OF_RESOURCES - No enough resoruces (such as out of memory).
|
|
@retval - Appropiate failure code on error
|
|
**/
|
|
EFI_STATUS
|
|
InitCpuAcpiTable (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_HANDLE *HandleBuffer;
|
|
UINTN NumberOfHandles;
|
|
EFI_FV_FILETYPE FileType;
|
|
UINT32 FvStatus;
|
|
EFI_FV_FILE_ATTRIBUTES Attributes;
|
|
UINTN Size;
|
|
UINTN Index;
|
|
EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
|
|
UINTN Instance;
|
|
EFI_ACPI_COMMON_HEADER *CurrentTable;
|
|
UINTN AcpiTableHandle;
|
|
|
|
FwVol = NULL;
|
|
|
|
///
|
|
/// Locate Firmware volume protocol.
|
|
/// There is little chance we can't find an FV protocol
|
|
///
|
|
Status = gBS->LocateHandleBuffer (
|
|
ByProtocol,
|
|
&gEfiFirmwareVolume2ProtocolGuid,
|
|
NULL,
|
|
&NumberOfHandles,
|
|
&HandleBuffer
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
///
|
|
/// Look for FV with ACPI storage file
|
|
///
|
|
FwVol = NULL;
|
|
for (Index = 0; Index < NumberOfHandles; Index++) {
|
|
///
|
|
/// Get the protocol on this handle
|
|
/// This should not fail because of LocateHandleBuffer
|
|
///
|
|
Status = gBS->HandleProtocol (
|
|
HandleBuffer[Index],
|
|
&gEfiFirmwareVolume2ProtocolGuid,
|
|
(VOID **) &FwVol
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
///
|
|
/// See if it has the ACPI storage file
|
|
///
|
|
Size = 0;
|
|
FvStatus = 0;
|
|
Status = FwVol->ReadFile (
|
|
FwVol,
|
|
&gCpuAcpiTableStorageGuid,
|
|
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 != NULL);
|
|
if (FwVol == NULL) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
///
|
|
/// Read tables from the storage file.
|
|
///
|
|
Instance = 0;
|
|
CurrentTable = NULL;
|
|
while (Status == EFI_SUCCESS) {
|
|
Status = FwVol->ReadSection (
|
|
FwVol,
|
|
&gCpuAcpiTableStorageGuid,
|
|
EFI_SECTION_RAW,
|
|
Instance,
|
|
(VOID **) &CurrentTable,
|
|
&Size,
|
|
&FvStatus
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
///
|
|
/// Check the table ID to modify the table
|
|
///
|
|
switch (((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->OemTableId) {
|
|
case (SIGNATURE_64 ('C', 'p', 'u', '0', 'I', 's', 't', 0)) :
|
|
mCpu0IstTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
|
|
if (gCpuNvsAreaProtocol->Area->PpmFlags & PPM_EIST) {
|
|
///
|
|
/// Patch the native _PSS package with the EIST values
|
|
///
|
|
Status = AcpiPatchPss ();
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
}
|
|
break;
|
|
case (SIGNATURE_64 ('C', 'p', 'u', '0', 'C', 's', 't', 0)) :
|
|
mCpu0CstTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
|
|
break;
|
|
case (SIGNATURE_64 ('C', 'p', 'u', '0', 'T', 's', 't', 0)) :
|
|
mCpu0TstTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
|
|
break;
|
|
case (SIGNATURE_64 ('A', 'p', 'I', 's', 't', 0, 0, 0)) :
|
|
mApIstTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
|
|
break;
|
|
case (SIGNATURE_64 ('A', 'p', 'C', 's', 't', 0, 0, 0)) :
|
|
mApCstTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
|
|
break;
|
|
case (SIGNATURE_64 ('A', 'p', 'T', 's', 't', 0, 0, 0)) :
|
|
mApTstTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
|
|
break;
|
|
case (SIGNATURE_64 ('C', 'p', 'u', 'S', 's', 'd', 't', 0)) :
|
|
mCpuSsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
|
|
break;
|
|
case (SIGNATURE_64 ('C', 'p', 'u', '0', 'H', 'w', 'p', 0)) :
|
|
mCpu0HwpTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
|
|
if (gCpuNvsAreaProtocol->Area->PpmFlags & PPM_HWP) {
|
|
///
|
|
/// Patch the native _CPC package with the lowest of highest performance values
|
|
///
|
|
Status = AcpiPatchCpc ();
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
}
|
|
break;
|
|
case (SIGNATURE_64 ('A', 'p', 'H', 'w', 'p', 0, 0, 0)) :
|
|
mApHwpTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
|
|
break;
|
|
case (SIGNATURE_64 ('C', 'p', 'u', '0', 'P', 's', 'd', 0)) :
|
|
mCpu0PsdTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
|
|
break;
|
|
case (SIGNATURE_64 ('A', 'p', 'P', 's', 'd', 0, 0, 0)) :
|
|
mApPsdTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
Instance++; // Increment the instance
|
|
CurrentTable = NULL;
|
|
}
|
|
}
|
|
///
|
|
/// Copy Cpu0Ist SSDT if EIST is enabled
|
|
///
|
|
if (gCpuNvsAreaProtocol->Area->PpmFlags & PPM_EIST) {
|
|
Status = RelocateAndUpdateCpuSsdtChecksum (&mCpu0IstTable);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
}
|
|
///
|
|
/// Copy Cpu0Psd SSDT if EIST or HWP is enabled
|
|
///
|
|
if ((gCpuNvsAreaProtocol->Area->PpmFlags & PPM_EIST) || (gCpuNvsAreaProtocol->Area->PpmFlags & PPM_HWP)) {
|
|
Status = RelocateAndUpdateCpuSsdtChecksum (&mCpu0PsdTable);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
}
|
|
///
|
|
/// Copy Cpu0Hwp & HwpLvt SSDT to reserved location and checksum them
|
|
///
|
|
if (gCpuNvsAreaProtocol->Area->PpmFlags & PPM_HWP) {
|
|
Status = RelocateAndUpdateCpuSsdtChecksum (&mCpu0HwpTable);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
///
|
|
/// If we are CMP, then the PPM tables are dynamically loaded:
|
|
/// We need to publish the CpuPm table to the ACPI tables, and move the CST
|
|
/// tables that are dynamically loaded to a separate location so that we can fix the
|
|
/// addresses in the CpuPm table.
|
|
/// Otherwise (non-CMP):
|
|
/// We need to publish CPU 0 tables only, and CST tables only if CST is enabled
|
|
///
|
|
if (gCpuNvsAreaProtocol->Area->PpmFlags & PPM_CMP) {
|
|
Status = RelocateAndUpdateCpuSsdtChecksum (&mApIstTable);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
///
|
|
/// Copy ApPsd SSDT if EIST or HWP is enabled
|
|
///
|
|
if ((gCpuNvsAreaProtocol->Area->PpmFlags & PPM_EIST) || (gCpuNvsAreaProtocol->Area->PpmFlags & PPM_HWP)) {
|
|
Status = RelocateAndUpdateCpuSsdtChecksum (&mApPsdTable);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
}
|
|
Status = RelocateAndUpdateCpuSsdtChecksum (&mCpu0CstTable);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = RelocateAndUpdateCpuSsdtChecksum (&mApCstTable);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
///
|
|
/// Copy Ap0Hwp SSDT to reserved location and checksum them
|
|
///
|
|
if (gCpuNvsAreaProtocol->Area->PpmFlags & PPM_HWP) {
|
|
Status = RelocateAndUpdateCpuSsdtChecksum (&mApHwpTable);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
}
|
|
} else {
|
|
//
|
|
// CMP disabled, so statically load the tables
|
|
//
|
|
// Add CST SSDT if C states are enabled
|
|
//
|
|
if (gCpuNvsAreaProtocol->Area->PpmFlags & PPM_C_STATES) {
|
|
AcpiTableHandle = 0;
|
|
Status = mAcpiTable->InstallAcpiTable (
|
|
mAcpiTable,
|
|
mCpu0CstTable,
|
|
mCpu0CstTable->Length,
|
|
&AcpiTableHandle
|
|
);
|
|
}
|
|
///
|
|
/// Since we are UP, there is no need for the CPU 1 tables
|
|
///
|
|
///
|
|
/// Free all tables, since they have been copied into ACPI tables by ACPI support protocol
|
|
///
|
|
FreePool (mCpu0CstTable);
|
|
FreePool (mApPsdTable);
|
|
FreePool (mApIstTable);
|
|
FreePool (mApCstTable);
|
|
}
|
|
///
|
|
/// Update the CpuSsdt SSDT table in the ACPI tables.
|
|
///
|
|
PatchCpuSsdtTable ();
|
|
AcpiTableHandle = 0;
|
|
Status = mAcpiTable->InstallAcpiTable (
|
|
mAcpiTable,
|
|
mCpuSsdtTable,
|
|
mCpuSsdtTable->Length,
|
|
&AcpiTableHandle
|
|
);
|
|
FreePool (mCpuSsdtTable);
|
|
if (gCpuNvsAreaProtocol->Area->PpmFlags & PPM_TSTATES) {
|
|
///
|
|
/// Load the Cpu0Tst SSDT table in the ACPI tables
|
|
///
|
|
AcpiTableHandle = 0;
|
|
Status = mAcpiTable->InstallAcpiTable (
|
|
mAcpiTable,
|
|
mCpu0TstTable,
|
|
mCpu0TstTable->Length,
|
|
&AcpiTableHandle
|
|
);
|
|
FreePool (mCpu0TstTable);
|
|
///
|
|
/// If the CMP is enabled then load the ApTst SSDT table in the ACPI tables
|
|
///
|
|
if (gCpuNvsAreaProtocol->Area->PpmFlags & PPM_CMP) {
|
|
AcpiTableHandle = 0;
|
|
Status = mAcpiTable->InstallAcpiTable (
|
|
mAcpiTable,
|
|
mApTstTable,
|
|
mApTstTable->Length,
|
|
&AcpiTableHandle
|
|
);
|
|
}
|
|
}
|
|
FreePool (mApTstTable);
|
|
return Status;
|
|
}
|
|
|