blob: 8c9e969b536f420d493ca542a200d889c4736f90 [file] [log] [blame]
/* $NoKeywords:$ */
/**
* @file
*
* AMD CPU Family Translation functions.
*
*
* @xrefitem bom "File Content Label" "Release Content"
* @e project: AGESA
* @e sub-project: CPU/Interface
* @e \$Revision: 56322 $ @e \$Date: 2011-07-11 16:51:42 -0600 (Mon, 11 Jul 2011) $
*
*/
/*
******************************************************************************
*
* Copyright (C) 2012 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.
*
******************************************************************************
*/
/*----------------------------------------------------------------------------------------
* M O D U L E S U S E D
*----------------------------------------------------------------------------------------
*/
#include "AGESA.h"
#include "amdlib.h"
#include "Ids.h"
#include "cpuRegisters.h"
#include "CommonReturns.h"
#include "GeneralServices.h"
#include "cpuFamilyTranslation.h"
#include "Filecode.h"
CODE_GROUP (G1_PEICC)
RDATA_GROUP (G2_PEI)
#define FILECODE PROC_CPU_CPUFAMILYTRANSLATION_FILECODE
/*----------------------------------------------------------------------------------------
* D E F I N I T I O N S A N D M A C R O S
*----------------------------------------------------------------------------------------
*/
/*----------------------------------------------------------------------------------------
* T Y P E D E F S A N D S T R U C T U R E S
*----------------------------------------------------------------------------------------
*/
CONST CPU_SPECIFIC_SERVICES ROMDATA cpuNullServices =
{
0,
(PF_CPU_DISABLE_PSTATE) CommonReturnAgesaSuccess,
(PF_CPU_TRANSITION_PSTATE) CommonReturnAgesaSuccess,
(PF_CPU_GET_IDD_MAX) CommonReturnFalse,
(PF_CPU_GET_TSC_RATE) CommonReturnAgesaSuccess,
(PF_CPU_GET_NB_FREQ) CommonReturnAgesaSuccess,
(PF_CPU_GET_MIN_MAX_NB_FREQ) CommonReturnAgesaSuccess,
(PF_CPU_GET_NB_PSTATE_INFO) CommonReturnFalse,
(PF_CPU_IS_NBCOF_INIT_NEEDED) CommonReturnAgesaSuccess,
(PF_CPU_GET_NB_IDD_MAX) CommonReturnFalse,
(PF_CPU_AP_INITIAL_LAUNCH) CommonReturnFalse,
(PF_CPU_NUMBER_OF_PHYSICAL_CORES) CommonReturnZero8,
(PF_CPU_AMD_GET_AP_MAILBOX_FROM_HARDWARE) CommonReturnAgesaSuccess,
(PF_CPU_SET_AP_CORE_NUMBER) CommonVoid,
(PF_CPU_GET_AP_CORE_NUMBER) CommonReturnZero32,
(PF_CPU_TRANSFER_AP_CORE_NUMBER) CommonVoid,
(PF_CORE_ID_POSITION_IN_INITIAL_APIC_ID) CommonReturnAgesaSuccess,
(PF_CPU_SAVE_FEATURES) CommonReturnAgesaSuccess,
(PF_CPU_WRITE_FEATURES) CommonReturnAgesaSuccess,
(PF_CPU_SET_WARM_RESET_FLAG) CommonReturnAgesaSuccess,
(PF_CPU_GET_WARM_RESET_FLAG) CommonReturnAgesaSuccess,
GetEmptyArray,
GetEmptyArray,
GetEmptyArray,
GetEmptyArray,
GetEmptyArray,
GetEmptyArray,
GetEmptyArray,
(PF_CPU_GET_PLATFORM_TYPE_SPECIFIC_INFO) CommonReturnAgesaSuccess,
(PF_IS_NB_PSTATE_ENABLED) CommonReturnFalse,
(PF_NEXT_LINK_HAS_HTFPY_FEATS) CommonReturnFalse,
(PF_SET_HT_PHY_REGISTER) CommonVoid,
(PF_GET_NEXT_HT_LINK_FEATURES) CommonVoid,
NULL,
NULL,
NULL,
NULL,
InitCacheDisabled,
(PF_GET_EARLY_INIT_TABLE) CommonVoid
};
/*----------------------------------------------------------------------------------------
* P R O T O T Y P E S O F L O C A L F U N C T I O N S
*----------------------------------------------------------------------------------------
*/
VOID
STATIC
GetCpuServices (
IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
IN UINT64 *MatchData,
OUT CONST VOID **CpuServices,
IN AMD_CONFIG_PARAMS *StdHeader
);
/*----------------------------------------------------------------------------------------
* E X P O R T E D F U N C T I O N S
*----------------------------------------------------------------------------------------
*/
extern CPU_FAMILY_SUPPORT_TABLE CpuSupportedFamiliesTable;
extern CPU_FAMILY_ID_XLAT_TABLE CpuSupportedFamilyIdTable;
/*---------------------------------------------------------------------------------------*/
/**
*
* Returns the logical ID of the desired processor. This will be obtained by
* reading the CPUID and converting it into a "logical ID" which is not package
* dependent.
*
* @param[in] Socket Socket
* @param[out] LogicalId The Processor's Logical ID
* @param[in] StdHeader Handle of Header for calling lib functions and services.
*
*/
VOID
GetLogicalIdOfSocket (
IN UINT32 Socket,
OUT CPU_LOGICAL_ID *LogicalId,
IN AMD_CONFIG_PARAMS *StdHeader
)
{
UINT32 RawCpuid;
PCI_ADDR PciAddress;
AGESA_STATUS AssumedSuccess;
RawCpuid = 0;
if (GetPciAddress (StdHeader, (UINT8)Socket, 0, &PciAddress, &AssumedSuccess)) {
PciAddress.Address.Function = FUNC_3;
PciAddress.Address.Register = CPUID_FMR;
LibAmdPciRead (AccessWidth32, PciAddress, &RawCpuid, StdHeader);
GetLogicalIdFromCpuid (RawCpuid, LogicalId, StdHeader);
} else {
LogicalId->Family = 0;
LogicalId->Revision = 0;
// Logical ID was not found.
IDS_ERROR_TRAP;
}
}
/*---------------------------------------------------------------------------------------*/
/**
*
* Returns the logical ID of the executing core. This will be obtained by reading
* the CPUID and converting it into a "logical ID" which is not package dependent.
*
* @param[out] LogicalId The Processor's Logical ID
* @param[in] StdHeader Handle of Header for calling lib functions and services.
*
*/
VOID
GetLogicalIdOfCurrentCore (
OUT CPU_LOGICAL_ID *LogicalId,
IN AMD_CONFIG_PARAMS *StdHeader
)
{
CPUID_DATA CpuidDataStruct;
LibAmdCpuidRead (AMD_CPUID_APICID_LPC_BID, &CpuidDataStruct, StdHeader);
GetLogicalIdFromCpuid (CpuidDataStruct.EAX_Reg, LogicalId, StdHeader);
}
/*---------------------------------------------------------------------------------------*/
/**
*
* Returns the logical ID of a processor with the given CPUID value. This
* will be obtained by converting it into a "logical ID" which is not package
* dependent.
*
* @param[in] RawCpuid The unprocessed CPUID value to be translated
* @param[out] LogicalId The Processor's Logical ID
* @param[in] StdHeader Handle of Header for calling lib functions and services
*
*/
VOID
GetLogicalIdFromCpuid (
IN UINT32 RawCpuid,
OUT CPU_LOGICAL_ID *LogicalId,
IN AMD_CONFIG_PARAMS *StdHeader
)
{
UINT8 i;
UINT8 k;
UINT8 NumberOfFamiliesSupported;
UINT8 NumberOfLogicalSubFamilies;
UINT8 LogicalIdEntries;
UINT32 j;
UINT32 RawFamily;
UINT32 CpuModelAndExtendedModel;
UINT64 LogicalFamily;
BOOLEAN IdNotFound;
BOOLEAN FamilyNotFound;
CONST PF_CPU_GET_SUBFAMILY_ID_ARRAY *SubFamilyIdPtr;
CPU_LOGICAL_ID_XLAT *CpuLogicalIdAndRevPtr;
CONST CPU_LOGICAL_ID_FAMILY_XLAT *ImageSupportedId;
IdNotFound = TRUE;
FamilyNotFound = TRUE;
CpuLogicalIdAndRevPtr = NULL;
ImageSupportedId = CpuSupportedFamilyIdTable.FamilyIdTable;
NumberOfFamiliesSupported = CpuSupportedFamilyIdTable.Elements;
RawFamily = ((RawCpuid & 0xF00) >> 8) + ((RawCpuid & 0xFF00000) >> 20);
RawCpuid &= (UINT32) CPU_FMS_MASK;
CpuModelAndExtendedModel = (UINT16) ((RawCpuid >> 8) | RawCpuid);
LogicalId->Family = 0;
LogicalId->Revision = 0;
for (i = 0; i < NumberOfFamiliesSupported && FamilyNotFound; i++) {
if (ImageSupportedId[i].Family == RawFamily) {
FamilyNotFound = FALSE;
LogicalId->Family = ImageSupportedId[i].UnknownRevision.Family;
LogicalId->Revision = ImageSupportedId[i].UnknownRevision.Revision;
NumberOfLogicalSubFamilies = ImageSupportedId[i].Elements;
SubFamilyIdPtr = ImageSupportedId[i].SubFamilyIdTable;
for (j = 0; j < NumberOfLogicalSubFamilies && IdNotFound; j++) {
SubFamilyIdPtr[j] ((CONST CPU_LOGICAL_ID_XLAT **)&CpuLogicalIdAndRevPtr, &LogicalIdEntries, &LogicalFamily, StdHeader);
ASSERT (CpuLogicalIdAndRevPtr != NULL);
for (k = 0; k < LogicalIdEntries; k++) {
if (CpuLogicalIdAndRevPtr[k].RawId == CpuModelAndExtendedModel) {
IdNotFound = FALSE;
LogicalId->Family = LogicalFamily;
LogicalId->Revision = CpuLogicalIdAndRevPtr[k].LogicalId;
break;
}
}
}
}
}
}
/*---------------------------------------------------------------------------------------*/
/**
*
* Retrieves a pointer to the desired processor's family specific services structure.
*
* @param[in] Socket The Processor in this Socket.
* @param[out] FunctionTable The Processor's Family Specific services.
* @param[in] StdHeader Handle of Header for calling lib functions and services.
*
*/
VOID
GetCpuServicesOfSocket (
IN UINT32 Socket,
OUT CONST CPU_SPECIFIC_SERVICES **FunctionTable,
IN AMD_CONFIG_PARAMS *StdHeader
)
{
GetFeatureServicesOfSocket (&CpuSupportedFamiliesTable,
Socket,
(CONST VOID **) FunctionTable,
StdHeader);
if (*FunctionTable == NULL) {
*FunctionTable = &cpuNullServices;
}
}
/*---------------------------------------------------------------------------------------*/
/**
*
* Retrieves a pointer to the desired processor's family specific services structure.
*
* @param[in] FamilyTable The table to search in.
* @param[in] Socket The Processor in this Socket.
* @param[out] CpuServices The Processor's Family Specific services.
* @param[in] StdHeader Handle of Header for calling lib functions and services.
*
*/
VOID
GetFeatureServicesOfSocket (
IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
IN UINT32 Socket,
OUT CONST VOID **CpuServices,
IN AMD_CONFIG_PARAMS *StdHeader
)
{
CPU_LOGICAL_ID CpuFamilyRevision;
GetLogicalIdOfSocket (Socket, &CpuFamilyRevision, StdHeader);
GetFeatureServicesFromLogicalId (FamilyTable, &CpuFamilyRevision, CpuServices, StdHeader);
}
/*---------------------------------------------------------------------------------------*/
/**
*
* Retrieves a pointer to the executing core's family specific services structure.
*
* @param[out] FunctionTable The Processor's Family Specific services.
* @param[in] StdHeader Handle of Header for calling lib functions and services.
*
*/
VOID
GetCpuServicesOfCurrentCore (
OUT CONST CPU_SPECIFIC_SERVICES **FunctionTable,
IN AMD_CONFIG_PARAMS *StdHeader
)
{
GetFeatureServicesOfCurrentCore (&CpuSupportedFamiliesTable,
(CONST VOID **) FunctionTable,
StdHeader);
if (*FunctionTable == NULL) {
*FunctionTable = &cpuNullServices;
}
}
/*---------------------------------------------------------------------------------------*/
/**
*
* Retrieves a pointer to the family specific services structure for a processor
* with the given logical ID.
*
* @param[in] FamilyTable The table to search in.
* @param[out] CpuServices The Processor's Family Specific services.
* @param[in] StdHeader Handle of Header for calling lib functions and services.
*
*/
VOID
GetFeatureServicesOfCurrentCore (
IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
OUT CONST VOID **CpuServices,
IN AMD_CONFIG_PARAMS *StdHeader
)
{
CPU_LOGICAL_ID CpuFamilyRevision;
GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader);
GetFeatureServicesFromLogicalId (FamilyTable, &CpuFamilyRevision, CpuServices, StdHeader);
}
/*---------------------------------------------------------------------------------------*/
/**
*
* Retrieves a pointer to the family specific services structure for a processor
* with the given logical ID.
*
* @param[in] LogicalId The Processor's logical ID.
* @param[out] FunctionTable The Processor's Family Specific services.
* @param[in] StdHeader Handle of Header for calling lib functions and services.
*
*/
VOID
GetCpuServicesFromLogicalId (
IN CPU_LOGICAL_ID *LogicalId,
OUT CONST CPU_SPECIFIC_SERVICES **FunctionTable,
IN AMD_CONFIG_PARAMS *StdHeader
)
{
GetFeatureServicesFromLogicalId (&CpuSupportedFamiliesTable,
LogicalId,
(CONST VOID **) FunctionTable,
StdHeader);
if (*FunctionTable == NULL) {
*FunctionTable = &cpuNullServices;
}
}
/*---------------------------------------------------------------------------------------*/
/**
*
* Retrieves a pointer to the family specific services structure for a processor
* with the given logical ID.
*
* @param[in] FamilyTable The table to search in.
* @param[in] LogicalId The Processor's logical ID.
* @param[out] CpuServices The Processor's Family Specific services.
* @param[in] StdHeader Handle of Header for calling lib functions and services.
*
*/
VOID
GetFeatureServicesFromLogicalId (
IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
IN CPU_LOGICAL_ID *LogicalId,
OUT CONST VOID **CpuServices,
IN AMD_CONFIG_PARAMS *StdHeader
)
{
GetCpuServices (FamilyTable, &LogicalId->Family, CpuServices, StdHeader);
}
/*---------------------------------------------------------------------------------------*/
/**
*
* Finds a family match in the given table, and returns the pointer to the
* appropriate table. If no match is found in the table, NULL will be returned.
*
* @param[in] FamilyTable The table to search in.
* @param[in] MatchData Family data that must match.
* @param[out] CpuServices The Processor's Family Specific services.
* @param[in] StdHeader Handle of Header for calling lib functions and services.
*
*/
VOID
STATIC
GetCpuServices (
IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
IN UINT64 *MatchData,
OUT CONST VOID **CpuServices,
IN AMD_CONFIG_PARAMS *StdHeader
)
{
BOOLEAN IsFamily;
UINT8 i;
UINT8 NumberOfFamiliesSupported;
CONST CPU_SPECIFIC_SERVICES_XLAT *ImageSupportedFamiliesPtr;
ImageSupportedFamiliesPtr = FamilyTable->FamilyTable;
NumberOfFamiliesSupported = FamilyTable->Elements;
IsFamily = FALSE;
for (i = 0; i < NumberOfFamiliesSupported; i++) {
if ((ImageSupportedFamiliesPtr[i].Family & *MatchData) != 0) {
IsFamily = TRUE;
break;
}
}
if (IsFamily) {
*CpuServices = ImageSupportedFamiliesPtr[i].TablePtr;
} else {
*CpuServices = NULL;
}
}
/*---------------------------------------------------------------------------------------*/
/**
* Used to stub out various family specific tables of information.
*
* @param[in] FamilySpecificServices The current Family Specific Services.
* @param[in] Empty NULL, to indicate no data.
* @param[out] NumberOfElements Zero, to indicate no data.
* @param[in] StdHeader Handle of Header for calling lib functions and services.
*
*/
VOID
GetEmptyArray (
IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
OUT CONST VOID **Empty,
OUT UINT8 *NumberOfElements,
IN AMD_CONFIG_PARAMS *StdHeader
)
{
*NumberOfElements = 0;
*Empty = NULL;
}