aboutsummaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuPstateTables.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuPstateTables.c')
-rwxr-xr-xsrc/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuPstateTables.c821
1 files changed, 821 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuPstateTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuPstateTables.c
new file mode 100755
index 0000000000..ed4eb02144
--- /dev/null
+++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuPstateTables.c
@@ -0,0 +1,821 @@
+/**
+ * @file
+ *
+ * AMD PSTATE, ACPI table related API functions.
+ *
+ * Contains code that generates the _PSS, _PCT, and other ACPI tables.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: CPU
+ * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 2010) $
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (c) 2011, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+
+/*
+ *----------------------------------------------------------------------------
+ * MODULES USED
+ *
+ *----------------------------------------------------------------------------
+ */
+#include "AGESA.h"
+#include "amdlib.h"
+#include "OptionPstate.h"
+#include "cpuLateInit.h"
+#include "cpuRegisters.h"
+#include "cpuFamilyTranslation.h"
+#include "GeneralServices.h"
+#include "cpuServices.h"
+#include "heapManager.h"
+#include "Ids.h"
+#include "Filecode.h"
+#include "GeneralServices.h"
+#include "cpuPstateTables.h"
+#include "cpuFeatures.h"
+#include "cpuC6State.h"
+#define FILECODE PROC_CPU_FEATURE_CPUPSTATETABLES_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+extern OPTION_PSTATE_LATE_CONFIGURATION OptionPstateLateConfiguration; // global user config record
+extern CPU_FAMILY_SUPPORT_TABLE PstateFamilyServiceTable;
+extern CPU_FAMILY_SUPPORT_TABLE C6FamilyServiceTable;
+
+STATIC ACPI_TABLE_HEADER ROMDATA CpuSsdtHdrStruct =
+{
+ {'S','S','D','T'},
+ 0,
+ 1,
+ 0,
+ {'A','M','D',' ',' ',' '},
+ {'P','O','W','E','R','N','O','W'},
+ 1,
+ {'A','M','D',' '},
+ 1
+};
+
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+AGESA_STATUS
+PStateLevelingMain (
+ IN OUT S_CPU_AMD_PSTATE *PStateStrucPtr,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ );
+AGESA_STATUS
+CreateAcpiTablesMain (
+ IN AMD_CONFIG_PARAMS *StdHeader,
+ IN PLATFORM_CONFIGURATION *PlatformConfig,
+ IN OUT VOID **SsdtPtr
+ );
+AGESA_STATUS
+CreateAcpiTablesStub (
+ IN AMD_CONFIG_PARAMS *StdHeader,
+ IN PLATFORM_CONFIGURATION *PlatformConfig,
+ IN OUT VOID **SsdtPtr
+ );
+
+/**
+ *---------------------------------------------------------------------------------------
+ *
+ * CalAcpiTablesSize
+ *
+ * Description:
+ * This function will calculate the size of ACPI PState tables
+ *
+ * Parameters:
+ * @param[in] *AmdPstatePtr
+ * @param[in] *PlatformConfig
+ * @param[in] *StdHeader
+ *
+ * @retval UINT32
+ *
+ *---------------------------------------------------------------------------------------
+ */
+STATIC UINT32
+CalAcpiTablesSize (
+ IN S_CPU_AMD_PSTATE *AmdPstatePtr,
+ IN PLATFORM_CONFIGURATION *PlatformConfig,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT32 ScopeSize;
+ UINT32 CoreCount;
+ UINT32 SocketCount;
+ UINT32 MaxCoreNumberInCurrentSocket;
+ UINT32 MaxSocketNumberInSystem;
+ UINT32 MaxPstateNumberInCurrentCore;
+ UINT32 CstObjSize;
+ PSTATE_LEVELING *PStateLevelingBufferStructPtr;
+ C6_FAMILY_SERVICES *C6FamilyServices;
+
+ ScopeSize = sizeof (ACPI_TABLE_HEADER);
+ CstObjSize = 0;
+ C6FamilyServices = NULL;
+
+ PStateLevelingBufferStructPtr = AmdPstatePtr->PStateLevelingStruc;
+ MaxSocketNumberInSystem = AmdPstatePtr->TotalSocketInSystem;
+
+ if (IsFeatureEnabled (C6Cstate, PlatformConfig, StdHeader)) {
+ GetFeatureServicesOfCurrentCore (&C6FamilyServiceTable, (CONST VOID **)&C6FamilyServices, StdHeader);
+ CstObjSize = C6FamilyServices->GetAcpiCstObj ();
+ }
+
+ for (SocketCount = 0; SocketCount < MaxSocketNumberInSystem; SocketCount++) {
+ MaxCoreNumberInCurrentSocket = PStateLevelingBufferStructPtr->TotalCoresInNode;
+ for (CoreCount = 0; CoreCount < MaxCoreNumberInCurrentSocket; CoreCount++) {
+ MaxPstateNumberInCurrentCore = PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateMaxValue + 1;
+ ScopeSize += (PCT_STRUCT_SIZE +
+ PSS_HEADER_STRUCT_SIZE +
+ (MaxPstateNumberInCurrentCore * PSS_BODY_STRUCT_SIZE) +
+ XPSS_HEADER_STRUCT_SIZE +
+ (MaxPstateNumberInCurrentCore * XPSS_BODY_STRUCT_SIZE) +
+ PSD_HEADER_STRUCT_SIZE +
+ PSD_BODY_STRUCT_SIZE +
+ PPC_HEADER_BODY_STRUCT_SIZE) + (SCOPE_STRUCT_SIZE - 1) +
+ CstObjSize;
+
+ }
+ ScopeSize += MaxCoreNumberInCurrentSocket;
+ PStateLevelingBufferStructPtr = (PSTATE_LEVELING *) ((UINT8 *) PStateLevelingBufferStructPtr + (UINTN) sizeof (PSTATE_LEVELING) + (UINTN) (PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateMaxValue * sizeof (S_PSTATE_VALUES)));
+ }
+
+ AmdPstatePtr->SizeOfBytes = ScopeSize;
+
+ return ScopeSize;
+}
+
+/**
+ *---------------------------------------------------------------------------------------
+ *
+ * CreateAcpiTables
+ *
+ * Description:
+ * This function will populate the ACPI PState tables
+ * This function should be called only from BSP
+ *
+ * Parameters:
+ * @param[in] StdHeader Handle to config for library and services
+ * @param[in] PlatformConfig Contains the power cap parameter
+ * @param[in,out] SsdtPtr ACPI SSDT table pointer
+ *
+ * @retval AGESA_STATUS
+ *
+ *---------------------------------------------------------------------------------------
+ */
+AGESA_STATUS
+CreateAcpiTables (
+ IN AMD_CONFIG_PARAMS *StdHeader,
+ IN PLATFORM_CONFIGURATION *PlatformConfig,
+ IN OUT VOID **SsdtPtr
+ )
+{
+ AGESA_TESTPOINT (TpProcCpuEntryPstate, StdHeader);
+ return ((*(OptionPstateLateConfiguration.PstateFeature)) (StdHeader, PlatformConfig, SsdtPtr));
+ // Note: Split config struct into PEI/DXE halves. This one is DXE.
+}
+
+/**--------------------------------------------------------------------------------------
+ *
+ * CreateAcpiTablesStub
+ *
+ * Description:
+ * This is the default routine for use when the PState option is NOT requested.
+ * The option install process will create and fill the transfer vector with
+ * the address of the proper routine (Main or Stub). The link optimizer will
+ * strip out of the .DLL the routine that is not used.
+ *
+ * Parameters:
+ * @param[in] StdHeader Handle to config for library and services
+ * @param[in] PlatformConfig Contains the power cap parameter
+ * @param[in,out] SsdtPtr ACPI SSDT table pointer
+ *
+ * @retval AGESA_STATUS
+ *
+ *---------------------------------------------------------------------------------------
+ **/
+AGESA_STATUS
+CreateAcpiTablesStub (
+ IN AMD_CONFIG_PARAMS *StdHeader,
+ IN PLATFORM_CONFIGURATION *PlatformConfig,
+ IN OUT VOID **SsdtPtr
+ )
+{
+ return AGESA_UNSUPPORTED;
+}
+
+/**--------------------------------------------------------------------------------------
+ *
+ * CreateAcpiTablesMain
+ *
+ * Description:
+ * This is the common routine for creating the ACPI information tables.
+ *
+ * Parameters:
+ * @param[in] StdHeader Handle to config for library and services
+ * @param[in] PlatformConfig Contains the power cap parameter
+ * @param[in,out] SsdtPtr ACPI SSDT table pointer
+ *
+ * @retval AGESA_STATUS
+ *
+ *---------------------------------------------------------------------------------------
+ **/
+AGESA_STATUS
+CreateAcpiTablesMain (
+ IN AMD_CONFIG_PARAMS *StdHeader,
+ IN PLATFORM_CONFIGURATION *PlatformConfig,
+ IN OUT VOID **SsdtPtr
+ )
+{
+ UINT32 i;
+ UINT32 j;
+ UINT32 k;
+ UINT32 TempVar8_a;
+ UINT32 PStateCount;
+ UINT32 CoreCount;
+ UINT32 CoreCount1;
+ UINT32 SocketCount;
+ UINT32 ScopeSize;
+ UINT32 TempVar_a;
+ UINT32 TempVar_b;
+ UINT32 TempVar_c;
+ UINT32 TempVar_d;
+ PCI_ADDR PciAddress;
+ UINT32 TransAndBusMastLatency;
+ UINT32 MaxCorePerNode;
+ UINT8 PStateMaxValueOnCurrentCore;
+ UINT8 *IntermediatePtr;
+ PSTATE_LEVELING *PStateLevelingBufferStructPtr;
+ AMD_CONFIG_PARAMS *AmdConfigParamsStructPtr;
+ SCOPE *ScopeAcpiTablesStructPtr;
+ SCOPE *ScopeAcpiTablesStructPtrTemp;
+ PCT_HEADER_BODY *pPctAcpiTables;
+ PSS_HEADER *pPssHeaderAcpiTables;
+ PSS_BODY *pPssBodyAcpiTables;
+ XPSS_HEADER *pXpssHeaderAcpiTables;
+ XPSS_BODY *pXpssBodyAcpiTables;
+ PSD_HEADER *pPsdHeaderAcpiTables;
+ PSD_BODY *pPsdBodyAcpiTables;
+ PPC_HEADER_BODY *pPpcHeaderBodyAcpiTables;
+ AGESA_BUFFER_PARAMS AgesaBuffer;
+ LOCATE_HEAP_PTR LocateHeapParams;
+ S_CPU_AMD_PSTATE *AmdPstatePtr;
+ BOOLEAN PstateCapEnable;
+ UINT32 PstateCapInputMilliWatts;
+ UINT8 PstateCapLevelSupport;
+ BOOLEAN PstateCapLevelSupportDetermined;
+ UINT8 LocalApicId;
+ AGESA_STATUS AgesaStatus;
+ AGESA_STATUS IgnoredStatus;
+ CPU_SPECIFIC_SERVICES *FamilySpecificServices;
+ PSTATE_CPU_FAMILY_SERVICES *FamilyServices;
+ BOOLEAN IsPsdDependent;
+ C6_FAMILY_SERVICES *C6FamilyServices;
+ //
+ //Initialize local variables
+ //
+ AmdConfigParamsStructPtr = StdHeader;
+ PstateCapEnable = FALSE;
+ PstateCapInputMilliWatts = PlatformConfig->PowerCeiling;
+ PstateCapLevelSupport = DEFAULT_PERF_PRESENT_CAP;
+ PstateCapLevelSupportDetermined = TRUE;
+ LocalApicId = 0;
+ AgesaStatus = AGESA_SUCCESS;
+ TempVar_c = 0;
+ ScopeAcpiTablesStructPtrTemp = NULL;
+ TransAndBusMastLatency = 0;
+ PStateCount = 0;
+ IsPsdDependent = !(PlatformConfig->ForcePstateIndependent);
+ FamilyServices = NULL;
+ C6FamilyServices = NULL;
+
+ ASSERT (IsBsp (StdHeader, &IgnoredStatus));
+
+ //
+ //Locate P-state gathered data heap.
+ //
+ LocateHeapParams.BufferHandle = AMD_PSTATE_DATA_BUFFER_HANDLE;
+
+ AGESA_TESTPOINT (TpProcCpuBeforeLocateSsdtBuffer, StdHeader);
+ if (HeapLocateBuffer (&LocateHeapParams, StdHeader) != AGESA_SUCCESS) {
+ return AGESA_ERROR;
+ }
+ AGESA_TESTPOINT (TpProcCpuAfterLocateSsdtBuffer, StdHeader);
+
+ AmdPstatePtr = (S_CPU_AMD_PSTATE *) LocateHeapParams.BufferPtr;
+ PStateLevelingBufferStructPtr = AmdPstatePtr->PStateLevelingStruc;
+
+ //
+ // Check if we need to create ACPI tables
+ //
+ if (PStateLevelingBufferStructPtr[0].CreateAcpiTables == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+
+ //
+ //Allocate rough buffer for AcpiTable, if AcpiPstateBufferPtr is NULL
+ //
+ if (*SsdtPtr == NULL) {
+ AgesaBuffer.StdHeader = *StdHeader;
+ //
+ //Do not know the actual size.. pre-calculate it.
+ //
+ AgesaBuffer.BufferLength = CalAcpiTablesSize (AmdPstatePtr, PlatformConfig, StdHeader);
+ AgesaBuffer.BufferHandle = AMD_PSTATE_ACPI_BUFFER_HANDLE;
+
+ AGESA_TESTPOINT (TpProcCpuBeforeAllocateSsdtBuffer, StdHeader);
+ if (AgesaAllocateBuffer (0, &AgesaBuffer) != AGESA_SUCCESS) {
+ return AGESA_ERROR;
+ }
+ AGESA_TESTPOINT (TpProcCpuAfterAllocateSsdtBuffer, StdHeader);
+ *SsdtPtr = AgesaBuffer.BufferPointer;
+ }
+
+ //SSDT header
+ LibAmdMemCopy (*SsdtPtr, (VOID *) &CpuSsdtHdrStruct, (UINTN) (sizeof (ACPI_TABLE_HEADER)), StdHeader);
+
+ IntermediatePtr = (UINT8 *) *SsdtPtr;
+ ScopeAcpiTablesStructPtr = (SCOPE *) &IntermediatePtr[sizeof (ACPI_TABLE_HEADER)];
+
+ SocketCount = AmdPstatePtr->TotalSocketInSystem;
+
+ // Initialize data variables
+ ScopeSize = 0;
+ CoreCount = 0;
+ for (i = 0; i < SocketCount; i++) {
+
+ MaxCorePerNode = PStateLevelingBufferStructPtr->TotalCoresInNode;
+
+ for (j = 0; j < MaxCorePerNode; j++) {
+
+ //
+ //Check Pstate Capability enable
+ //
+ if (PstateCapInputMilliWatts != 0) {
+ PstateCapEnable = TRUE;
+ PstateCapLevelSupportDetermined = FALSE;
+ }
+
+ PStateMaxValueOnCurrentCore = PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateMaxValue;
+
+ CoreCount++;
+ // Set Name Scope for CPU0, 1, 2, ..... n
+ // CPU0 to CPUn will name as C000 to Cnnn
+ // -----------------------------------------
+ ScopeAcpiTablesStructPtr->ScopeOpcode = SCOPE_OPCODE;
+ // This value will be filled at the end of this function
+ // Since at this time, we don't know how many Pstates we
+ // would have
+ ScopeAcpiTablesStructPtr->ScopeLength = 0;
+ ScopeAcpiTablesStructPtr->ScopeValue1 = SCOPE_VALUE1;
+ ScopeAcpiTablesStructPtr->ScopeValue2 = SCOPE_VALUE2;
+ ScopeAcpiTablesStructPtr->ScopeNamePt1a__ = SCOPE_NAME__;
+ if (PlatformConfig->ProcessorScopeInSb) {
+ ScopeAcpiTablesStructPtr->ScopeNamePt1a_P = SCOPE_NAME_S;
+ ScopeAcpiTablesStructPtr->ScopeNamePt1a_R = SCOPE_NAME_B;
+ } else {
+ ScopeAcpiTablesStructPtr->ScopeNamePt1a_P = SCOPE_NAME_P;
+ ScopeAcpiTablesStructPtr->ScopeNamePt1a_R = SCOPE_NAME_R;
+ }
+ ScopeAcpiTablesStructPtr->ScopeNamePt1b__ = SCOPE_NAME__;
+
+ ASSERT ((PlatformConfig->ProcessorScopeName0 >= 'A') && (PlatformConfig->ProcessorScopeName0 <= 'Z'))
+ ASSERT (((PlatformConfig->ProcessorScopeName1 >= 'A') && (PlatformConfig->ProcessorScopeName1 <= 'Z')) || \
+ ((PlatformConfig->ProcessorScopeName1 >= '0') && (PlatformConfig->ProcessorScopeName1 <= '9')) || \
+ (PlatformConfig->ProcessorScopeName1 == '_'))
+
+ ScopeAcpiTablesStructPtr->ScopeNamePt2a_C = PlatformConfig->ProcessorScopeName0;
+ ScopeAcpiTablesStructPtr->ScopeNamePt2a_P = PlatformConfig->ProcessorScopeName1;
+
+ TempVar8_a = ((CoreCount - 1) >> 4) & 0x0F;
+ ScopeAcpiTablesStructPtr->ScopeNamePt2a_U = (UINT8) (SCOPE_NAME_0 + TempVar8_a);
+
+ TempVar8_a = (CoreCount - 1) & 0x0F;
+ if (TempVar8_a < 0xA) {
+ ScopeAcpiTablesStructPtr->ScopeNamePt2a_0 = (UINT8) (SCOPE_NAME_0 + TempVar8_a);
+ } else {
+ ScopeAcpiTablesStructPtr->ScopeNamePt2a_0 = (UINT8) (SCOPE_NAME_A + TempVar8_a - 0xA);
+ }
+
+ //
+ // Increment and typecast the pointer
+ //
+ ScopeAcpiTablesStructPtr++;
+ pPctAcpiTables = (PCT_HEADER_BODY *) ScopeAcpiTablesStructPtr;
+ ScopeAcpiTablesStructPtr--;
+ ScopeAcpiTablesStructPtrTemp = ScopeAcpiTablesStructPtr;
+ ScopeAcpiTablesStructPtrTemp++;
+
+ if (OptionPstateLateConfiguration.CfgPstatePct) {
+ //
+ // Set _PCT Table
+ // --------------
+ pPctAcpiTables->NameOpcode = NAME_OPCODE;
+ pPctAcpiTables->PctName_a__ = PCT_NAME__;
+ pPctAcpiTables->PctName_a_P = PCT_NAME_P;
+ pPctAcpiTables->PctName_a_C = PCT_NAME_C;
+ pPctAcpiTables->PctName_a_T = PCT_NAME_T;
+ pPctAcpiTables->Value1 = PCT_VALUE1;
+ pPctAcpiTables->Value2 = PCT_VALUE2;
+ pPctAcpiTables->Value3 = PCT_VALUE3;
+ pPctAcpiTables->GenericRegDescription1 = GENERIC_REG_DESCRIPTION;
+ pPctAcpiTables->Length1 = PCT_LENGTH;
+ pPctAcpiTables->AddressSpaceId1 = PCT_ADDRESS_SPACE_ID;
+ pPctAcpiTables->RegisterBitWidth1 = PCT_REGISTER_BIT_WIDTH;
+ pPctAcpiTables->RegisterBitOffset1 = PCT_REGISTER_BIT_OFFSET;
+ pPctAcpiTables->Reserved1 = PCT_RESERVED;
+ pPctAcpiTables->ControlRegAddressLo = PCT_CONTROL_REG_LO;
+ pPctAcpiTables->ControlRegAddressHi = PCT_CONTROL_REG_HI;
+ pPctAcpiTables->Value4 = PCT_VALUE4;
+ pPctAcpiTables->Value5 = PCT_VALUE5;
+ pPctAcpiTables->GenericRegDescription2 = GENERIC_REG_DESCRIPTION;
+ pPctAcpiTables->Length2 = PCT_LENGTH;
+ pPctAcpiTables->AddressSpaceId2 = PCT_ADDRESS_SPACE_ID;
+ pPctAcpiTables->RegisterBitWidth2 = PCT_REGISTER_BIT_WIDTH;
+ pPctAcpiTables->RegisterBitOffset2 = PCT_REGISTER_BIT_OFFSET;
+ pPctAcpiTables->Reserved2 = PCT_RESERVED;
+ pPctAcpiTables->StatusRegAddressLo = PCT_STATUS_REG_LO;
+ pPctAcpiTables->StatusRegAddressHi = PCT_STATUS_REG_HI;
+ pPctAcpiTables->Value6 = PCT_VALUE6;
+
+ // Set _PSS Table - START
+ //------------------------
+
+ // Increment and then typecast the pointer
+ pPctAcpiTables++;
+ TempVar_c += PCT_STRUCT_SIZE;
+
+ ScopeAcpiTablesStructPtrTemp = (SCOPE *) pPctAcpiTables;
+ } // end of OptionPstateLateConfiguration.CfgPstatePct
+
+ pPssHeaderAcpiTables = (PSS_HEADER *) pPctAcpiTables;
+
+ if (OptionPstateLateConfiguration.CfgPstatePss) {
+ //
+ // Set _PSS Header
+ // Note: Set the pssLength and numOfItemsInPss later
+ //---------------------------------------------------
+ pPssHeaderAcpiTables->NameOpcode = NAME_OPCODE;
+ pPssHeaderAcpiTables->PssName_a__ = PSS_NAME__;
+ pPssHeaderAcpiTables->PssName_a_P = PSS_NAME_P;
+ pPssHeaderAcpiTables->PssName_a_S = PSS_NAME_S;
+ pPssHeaderAcpiTables->PssName_b_S = PSS_NAME_S;
+ pPssHeaderAcpiTables->PkgOpcode = PACKAGE_OPCODE;
+
+ pPssHeaderAcpiTables++;
+ }// end of PSS Header if OptionPstateLateConfiguration.CfgPstatePss
+
+ pPssBodyAcpiTables = (PSS_BODY *) pPssHeaderAcpiTables;
+
+ if (OptionPstateLateConfiguration.CfgPstatePss) {
+ // Restore the pPssHeaderAcpiTables
+ pPssHeaderAcpiTables--;
+
+ // Set _PSS Body
+ //---------------
+ PStateCount = 0;
+
+ //
+ //Calculate pci address for socket only
+ //
+ GetPciAddress (StdHeader, (UINT32) PStateLevelingBufferStructPtr->SocketNumber, 0, &PciAddress, &IgnoredStatus);
+ TransAndBusMastLatency = 0;
+ GetCpuServicesOfSocket ((UINT32) PStateLevelingBufferStructPtr->SocketNumber, &FamilySpecificServices, StdHeader);
+ ASSERT (FamilySpecificServices != NULL);
+ FamilySpecificServices->GetPstateLatency (FamilySpecificServices,
+ PStateLevelingBufferStructPtr,
+ &PciAddress,
+ &TransAndBusMastLatency,
+ StdHeader);
+
+ for (k = 0; k <= PStateMaxValueOnCurrentCore; k++) {
+ if (PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateStruct[k].PStateEnable != 0) {
+ pPssBodyAcpiTables->PkgOpcode = PACKAGE_OPCODE;
+ pPssBodyAcpiTables->PkgLength = PSS_PKG_LENGTH;
+ pPssBodyAcpiTables->NumOfElements = PSS_NUM_OF_ELEMENTS;
+ pPssBodyAcpiTables->DwordPrefixOpcode1 = DWORD_PREFIX_OPCODE;
+
+ pPssBodyAcpiTables->Frequency =
+ PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateStruct[k].CoreFreq;
+
+ pPssBodyAcpiTables->DwordPrefixOpcode2 = DWORD_PREFIX_OPCODE;
+
+ pPssBodyAcpiTables->Power =
+ PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateStruct[k].Power;
+
+ if (PstateCapEnable && (!PstateCapLevelSupportDetermined) && (PstateCapInputMilliWatts >= pPssBodyAcpiTables->Power)) {
+ PstateCapLevelSupport = (UINT8) k;
+ PstateCapLevelSupportDetermined = TRUE;
+ }
+
+ pPssBodyAcpiTables->DwordPrefixOpcode3 = DWORD_PREFIX_OPCODE;
+
+ pPssBodyAcpiTables->TransitionLatency = TransAndBusMastLatency;
+ pPssBodyAcpiTables->DwordPrefixOpcode4 = DWORD_PREFIX_OPCODE;
+ pPssBodyAcpiTables->BusMasterLatency = TransAndBusMastLatency;
+ pPssBodyAcpiTables->DwordPrefixOpcode5 = DWORD_PREFIX_OPCODE;
+ pPssBodyAcpiTables->Control = k;
+ pPssBodyAcpiTables->DwordPrefixOpcode6 = DWORD_PREFIX_OPCODE;
+ pPssBodyAcpiTables->Status = k;
+
+ pPssBodyAcpiTables++;
+ PStateCount++;
+ }
+
+ } // for (k = 0; k < MPPSTATE_MAXIMUM_STATES; k++)
+
+ if (PstateCapEnable && (!PstateCapLevelSupportDetermined)) {
+ PstateCapLevelSupport = PStateMaxValueOnCurrentCore;
+ }
+
+ // Set _PSS Header again
+ // Now Set pssLength and numOfItemsInPss
+ //---------------------------------------
+ TempVar_a = (PStateCount * PSS_BODY_STRUCT_SIZE) + 3;
+ if (TempVar_a > 63) {
+ TempVar_b = TempVar_a;
+ TempVar_d = ((TempVar_b << 4) & 0x0000FF00);
+ TempVar_d = TempVar_d | ((TempVar_b & 0x0000000F) | 0x00000040);
+ TempVar_a = (UINT16) TempVar_d;
+ }
+
+ pPssHeaderAcpiTables->PssLength = (UINT16) TempVar_a;
+ pPssHeaderAcpiTables->NumOfItemsInPss = (UINT8) PStateCount;
+ TempVar_c += (PSS_HEADER_STRUCT_SIZE + (PStateCount * PSS_BODY_STRUCT_SIZE));
+
+ ScopeAcpiTablesStructPtrTemp = (SCOPE *) pPssBodyAcpiTables;
+ } // end of PSS Body if OptionPstateLateConfiguration.CfgPstatePss
+
+ //
+ // Set XPSS Table - START
+ //------------------------
+ // Typecast the pointer
+ pXpssHeaderAcpiTables = (XPSS_HEADER *) pPssBodyAcpiTables;
+
+ if (OptionPstateLateConfiguration.CfgPstateXpss) {
+ // Set XPSS Header
+ // Note: Set the pssLength and numOfItemsInPss later
+ //---------------------------------------------------
+ pXpssHeaderAcpiTables->NameOpcode = NAME_OPCODE;
+ pXpssHeaderAcpiTables->XpssName_a_X = PSS_NAME_X;
+ pXpssHeaderAcpiTables->XpssName_a_P = PSS_NAME_P;
+ pXpssHeaderAcpiTables->XpssName_a_S = PSS_NAME_S;
+ pXpssHeaderAcpiTables->XpssName_b_S = PSS_NAME_S;
+ pXpssHeaderAcpiTables->PkgOpcode = PACKAGE_OPCODE;
+
+ // Increment and then typecast the pointer
+ pXpssHeaderAcpiTables++;
+ }//end of XPSS header if OptionPstateLateConfiguration.CfgPstateXpss
+
+ pXpssBodyAcpiTables = (XPSS_BODY *) pXpssHeaderAcpiTables;
+
+ if (OptionPstateLateConfiguration.CfgPstateXpss) {
+ // Restore the pXpssHeaderAcpiTables
+ pXpssHeaderAcpiTables--;
+
+ // Set XPSS Body
+ //---------------
+ for (k = 0; k <= PStateMaxValueOnCurrentCore; k++) {
+ if (PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateStruct[k].PStateEnable != 0) {
+ pXpssBodyAcpiTables->PkgOpcode = PACKAGE_OPCODE;
+ pXpssBodyAcpiTables->PkgLength = XPSS_PKG_LENGTH;
+ pXpssBodyAcpiTables->NumOfElements = XPSS_NUM_OF_ELEMENTS;
+ pXpssBodyAcpiTables->XpssValueTbd = 04;
+ pXpssBodyAcpiTables->DwordPrefixOpcode1 = DWORD_PREFIX_OPCODE;
+
+ pXpssBodyAcpiTables->Frequency =
+ PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateStruct[k].CoreFreq;
+
+ pXpssBodyAcpiTables->DwordPrefixOpcode2 = DWORD_PREFIX_OPCODE;
+
+ pXpssBodyAcpiTables->Power =
+ PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateStruct[k].Power;
+
+ pXpssBodyAcpiTables->DwordPrefixOpcode3 = DWORD_PREFIX_OPCODE;
+
+ pXpssBodyAcpiTables->TransitionLatency = TransAndBusMastLatency;
+ pXpssBodyAcpiTables->DwordPrefixOpcode4 = DWORD_PREFIX_OPCODE;
+ pXpssBodyAcpiTables->BusMasterLatency = TransAndBusMastLatency;
+ pXpssBodyAcpiTables->ControlBuffer = XPSS_ACPI_BUFFER;
+ pXpssBodyAcpiTables->ControlLo = k;
+ pXpssBodyAcpiTables->ControlHi = 0;
+ pXpssBodyAcpiTables->StatusBuffer = XPSS_ACPI_BUFFER;
+ pXpssBodyAcpiTables->StatusLo = k;
+ pXpssBodyAcpiTables->StatusHi = 0;
+ pXpssBodyAcpiTables->ControlMaskBuffer = XPSS_ACPI_BUFFER;
+ pXpssBodyAcpiTables->ControlMaskLo = 0;
+ pXpssBodyAcpiTables->ControlMaskHi = 0;
+ pXpssBodyAcpiTables->StatusMaskBuffer = XPSS_ACPI_BUFFER;
+ pXpssBodyAcpiTables->StatusMaskLo = 0;
+ pXpssBodyAcpiTables->StatusMaskHi = 0;
+
+ pXpssBodyAcpiTables++;
+ }
+ } // for (k = 0; k < MPPSTATE_MAXIMUM_STATES; k++)
+
+ // Set XPSS Header again
+ // Now Set pssLength and numOfItemsInPss
+ //---------------------------------------
+ TempVar_a = (PStateCount * XPSS_BODY_STRUCT_SIZE) + 3;
+ if (TempVar_a > 63) {
+ TempVar_b = TempVar_a;
+ TempVar_d = ((TempVar_b << 4) & 0x0000FF00);
+ TempVar_d = TempVar_d | ((TempVar_b & 0x0000000F) | 0x00000040);
+ TempVar_a = (UINT16) TempVar_d;
+ }
+
+ pXpssHeaderAcpiTables->XpssLength = (UINT16) TempVar_a;
+ pXpssHeaderAcpiTables->NumOfItemsInXpss = (UINT8) PStateCount;
+ TempVar_c += (XPSS_HEADER_STRUCT_SIZE + (PStateCount * XPSS_BODY_STRUCT_SIZE));
+
+ ScopeAcpiTablesStructPtrTemp = (SCOPE *) pXpssBodyAcpiTables;
+ } //end of XPSS Body OptionPstateLateConfiguration.CfgPstateXpss
+
+ //
+ // Set _PSD Table - START
+ //------------------------
+ // Typecast the pointer
+ pPsdHeaderAcpiTables = (PSD_HEADER *) pXpssBodyAcpiTables;
+
+ //
+ // Get Total Cores Per Node
+ /// @todo Maybe this should ask for single core Sockets not single core nodes?
+ if (GetActiveCoresInGivenSocket ((UINT32) PStateLevelingBufferStructPtr->SocketNumber, &CoreCount1, AmdConfigParamsStructPtr)) {
+ if ((CoreCount1 != 1) && (OptionPstateLateConfiguration.CfgPstatePsd)) {
+ //
+ // Set _PSD Header
+ //-----------------
+ pPsdHeaderAcpiTables->NameOpcode = NAME_OPCODE;
+ pPsdHeaderAcpiTables->PkgOpcode = PACKAGE_OPCODE;
+ pPsdHeaderAcpiTables->PsdLength = PSD_HEADER_LENGTH;
+ pPsdHeaderAcpiTables->Value1 = PSD_VALUE1;
+
+ // Set _PSD Header
+ pPsdHeaderAcpiTables->PsdName_a__ = PSD_NAME__;
+ pPsdHeaderAcpiTables->PsdName_a_P = PSD_NAME_P;
+ pPsdHeaderAcpiTables->PsdName_a_S = PSD_NAME_S;
+ pPsdHeaderAcpiTables->PsdName_a_D = PSD_NAME_D;
+
+ // Typecast the pointer
+ pPsdHeaderAcpiTables++;
+ TempVar_c += PSD_HEADER_STRUCT_SIZE;
+ } // end of PSD Header if (CoreCount1 != 1) && (OptionPstateLateConfiguration.CfgPstatePsd)
+ }
+ pPsdBodyAcpiTables = (PSD_BODY *) pPsdHeaderAcpiTables;
+
+ if ((CoreCount1 != 1) && (OptionPstateLateConfiguration.CfgPstatePsd)) {
+ pPsdHeaderAcpiTables--;
+ //
+ // Set _PSD Body
+ //----------------
+ pPsdBodyAcpiTables->PkgOpcode = PACKAGE_OPCODE;
+ pPsdBodyAcpiTables->PkgLength = PSD_PKG_LENGTH;
+ pPsdBodyAcpiTables->NumOfEntries = NUM_OF_ENTRIES;
+ pPsdBodyAcpiTables->BytePrefixOpcode1 = BYTE_PREFIX_OPCODE;
+ pPsdBodyAcpiTables->PsdNumOfEntries = PSD_NUM_OF_ENTRIES;
+ pPsdBodyAcpiTables->BytePrefixOpcode2 = BYTE_PREFIX_OPCODE;
+ pPsdBodyAcpiTables->PsdRevision = PSD_REVISION;
+ pPsdBodyAcpiTables->DwordPrefixOpcode1 = DWORD_PREFIX_OPCODE;
+ //
+ //Get ApicId from AMD CPU general service.
+ //Basically, DependencyDomain should be LocalApicId for each core PSD independent.
+ //
+ GetApicId (StdHeader, (UINT32) PStateLevelingBufferStructPtr->SocketNumber, j, &LocalApicId, &AgesaStatus);
+
+ GetFeatureServicesOfCurrentCore (&PstateFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader);
+ if (FamilyServices != NULL) {
+ IsPsdDependent = FamilyServices->IsPstatePsdDependent (FamilyServices, PlatformConfig, StdHeader);
+ }
+
+ if (IsPsdDependent) {
+ pPsdBodyAcpiTables->DependencyDomain = PSD_DEPENDENCY_DOMAIN;
+ pPsdBodyAcpiTables->CoordinationType = PSD_COORDINATION_TYPE_SW_ALL;
+ pPsdBodyAcpiTables->NumOfProcessors = CoreCount1;
+ } else {
+ pPsdBodyAcpiTables->DependencyDomain = LocalApicId;
+ pPsdBodyAcpiTables->CoordinationType = PSD_COORDINATION_TYPE_SW_ANY;
+ pPsdBodyAcpiTables->NumOfProcessors = PSD_NUM_OF_PROCESSORS;
+ }
+
+ pPsdBodyAcpiTables->DwordPrefixOpcode2 = DWORD_PREFIX_OPCODE;
+ pPsdBodyAcpiTables->DwordPrefixOpcode3 = DWORD_PREFIX_OPCODE;
+
+ pPsdBodyAcpiTables++;
+ ScopeAcpiTablesStructPtrTemp = (SCOPE *) pPsdBodyAcpiTables;
+ TempVar_c += PSD_BODY_STRUCT_SIZE;
+ }// end of PSD Body if (CoreCount1 != 1) || (OptionPstateLateConfiguration.CfgPstatePsd)
+
+ //
+ // Set _PPC Table - START
+ //------------------------
+
+ // Typecast the pointer
+
+ pPpcHeaderBodyAcpiTables = (PPC_HEADER_BODY *) pPsdBodyAcpiTables;
+
+ // Set _PPC Header and Body
+ //--------------------------
+ if (OptionPstateLateConfiguration.CfgPstatePpc) {
+ pPpcHeaderBodyAcpiTables->NameOpcode = NAME_OPCODE;
+ pPpcHeaderBodyAcpiTables->PpcName_a__ = PPC_NAME__;
+ pPpcHeaderBodyAcpiTables->PpcName_a_P = PPC_NAME_P;
+ pPpcHeaderBodyAcpiTables->PpcName_b_P = PPC_NAME_P;
+ pPpcHeaderBodyAcpiTables->PpcName_a_C = PPC_NAME_C;
+ pPpcHeaderBodyAcpiTables->Value1 = PPC_VALUE1;
+
+ pPpcHeaderBodyAcpiTables->DefaultPerfPresentCap = PstateCapLevelSupport;
+ TempVar_c += PPC_HEADER_BODY_STRUCT_SIZE;
+ // Increment and typecast the pointer
+ pPpcHeaderBodyAcpiTables++;
+ ScopeAcpiTablesStructPtrTemp = (SCOPE *) pPpcHeaderBodyAcpiTables;
+ }// end of OptionPstateLateConfiguration.CfgPstatePpc
+
+ // If C6 is enabled, generate the corresponding ACPI object for it
+ if (IsFeatureEnabled (C6Cstate, PlatformConfig, StdHeader)) {
+ GetFeatureServicesOfCurrentCore (&C6FamilyServiceTable, (CONST VOID **)&C6FamilyServices, StdHeader);
+ C6FamilyServices->CreateAcpiCstObj ((VOID *) &ScopeAcpiTablesStructPtrTemp, StdHeader);
+ TempVar_c += C6FamilyServices->GetAcpiCstObj ();
+ }
+
+ //
+ // Now update the SCOPE Length field
+ //
+ {
+ TempVar_c += (SCOPE_STRUCT_SIZE - 1);
+ ScopeSize += TempVar_c;
+
+ TempVar_d = ((TempVar_c << 4) & 0x0000FF00);
+ TempVar_d |= ((TempVar_c & 0x0000000F) | 0x00000040);
+ TempVar_a = TempVar_d;
+ ScopeAcpiTablesStructPtr->ScopeLength = (UINT16) TempVar_a;
+ TempVar_c = 0;
+ }
+
+ // Increment and typecast the pointer
+ ScopeAcpiTablesStructPtr = ScopeAcpiTablesStructPtrTemp;
+
+ } // for (j = 0; j < MPPSTATE_MAX_CORES_PER_NODE; j++)
+
+ //
+ //Calculate next node buffer address
+ //
+ PStateLevelingBufferStructPtr = (PSTATE_LEVELING *) ((UINT8 *) PStateLevelingBufferStructPtr + (UINTN) sizeof (PSTATE_LEVELING) + (UINTN) (PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateMaxValue * sizeof (S_PSTATE_VALUES)));
+
+ } // for (i = 0; i < NodeCount; i++)
+
+ //Update SSDT header Checksum
+ ((ACPI_TABLE_HEADER *) *SsdtPtr)->TableLength = (ScopeSize + CoreCount + sizeof (ACPI_TABLE_HEADER));
+ ChecksumAcpiTable ((ACPI_TABLE_HEADER *) *SsdtPtr, StdHeader);
+
+ return AGESA_SUCCESS;
+}
+
+
+