5 * AMD CPU Family Translation functions.
8 * @xrefitem bom "File Content Label" "Release Content"
10 * @e sub-project: CPU/Interface
11 * @e \$Revision: 37150 $ @e \$Date: 2010-08-31 23:53:37 +0800 (Tue, 31 Aug 2010) $
15 *****************************************************************************
17 * Copyright (c) 2011, Advanced Micro Devices, Inc.
18 * All rights reserved.
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions are met:
22 * * Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 * * Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in the
26 * documentation and/or other materials provided with the distribution.
27 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
28 * its contributors may be used to endorse or promote products derived
29 * from this software without specific prior written permission.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
32 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
35 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
38 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
40 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 * ***************************************************************************
46 /*----------------------------------------------------------------------------------------
47 * M O D U L E S U S E D
48 *----------------------------------------------------------------------------------------
53 #include "cpuRegisters.h"
54 #include "CommonReturns.h"
55 #include "GeneralServices.h"
56 #include "cpuFamilyTranslation.h"
59 RDATA_GROUP (G1_PEICC)
61 #define FILECODE PROC_CPU_CPUFAMILYTRANSLATION_FILECODE
63 /*----------------------------------------------------------------------------------------
64 * D E F I N I T I O N S A N D M A C R O S
65 *----------------------------------------------------------------------------------------
68 /*----------------------------------------------------------------------------------------
69 * T Y P E D E F S A N D S T R U C T U R E S
70 *----------------------------------------------------------------------------------------
73 CONST CPU_SPECIFIC_SERVICES ROMDATA cpuNullServices =
76 (PF_CPU_DISABLE_PSTATE) CommonReturnAgesaSuccess,
77 (PF_CPU_TRANSITION_PSTATE) CommonReturnAgesaSuccess,
78 (PF_CPU_GET_IDD_MAX) CommonReturnFalse,
79 (PF_CPU_GET_TSC_RATE) CommonReturnAgesaSuccess,
80 (PF_CPU_GET_NB_FREQ) CommonReturnAgesaSuccess,
81 (PF_CPU_GET_NB_PSTATE_INFO) CommonReturnFalse,
82 (PF_CPU_IS_NBCOF_INIT_NEEDED) CommonReturnAgesaSuccess,
83 (PF_CPU_AP_INITIAL_LAUNCH) CommonReturnFalse,
84 (PF_CPU_NUMBER_OF_BRANDSTRING_CORES) CommonReturnZero8,
85 (PF_CPU_AMD_GET_AP_MAILBOX_FROM_HARDWARE) CommonReturnAgesaSuccess,
86 (PF_CPU_SET_AP_CORE_NUMBER) CommonVoid,
87 (PF_CPU_GET_AP_CORE_NUMBER) CommonReturnZero32,
88 (PF_CPU_TRANSFER_AP_CORE_NUMBER) CommonVoid,
89 (PF_CORE_ID_POSITION_IN_INITIAL_APIC_ID) CommonReturnAgesaSuccess,
90 (PF_CPU_SAVE_FEATURES) CommonReturnAgesaSuccess,
91 (PF_CPU_WRITE_FEATURES) CommonReturnAgesaSuccess,
92 (PF_CPU_SET_WARM_RESET_FLAG) CommonReturnAgesaSuccess,
93 (PF_CPU_GET_WARM_RESET_FLAG) CommonReturnAgesaSuccess,
101 (PF_CPU_GET_PLATFORM_TYPE_SPECIFIC_INFO) CommonReturnAgesaSuccess,
102 (PF_IS_NB_PSTATE_ENABLED) CommonReturnFalse,
103 (PF_NEXT_LINK_HAS_HTFPY_FEATS) CommonReturnFalse,
104 (PF_SET_HT_PHY_REGISTER) CommonVoid,
105 (PF_GET_NEXT_HT_LINK_FEATURES) CommonVoid,
111 (PF_GET_EARLY_INIT_TABLE) CommonVoid
114 /*----------------------------------------------------------------------------------------
115 * 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
116 *----------------------------------------------------------------------------------------
121 IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
122 IN UINT64 *MatchData,
123 OUT CONST VOID **CpuServices,
124 IN AMD_CONFIG_PARAMS *StdHeader
127 /*----------------------------------------------------------------------------------------
128 * E X P O R T E D F U N C T I O N S
129 *----------------------------------------------------------------------------------------
131 extern CPU_FAMILY_SUPPORT_TABLE CpuSupportedFamiliesTable;
132 extern CPU_FAMILY_ID_XLAT_TABLE CpuSupportedFamilyIdTable;
134 /*---------------------------------------------------------------------------------------*/
137 * Returns the logical ID of the desired processor. This will be obtained by
138 * reading the CPUID and converting it into a "logical ID" which is not package
141 * @param[in] Socket Socket
142 * @param[out] LogicalId The Processor's Logical ID
143 * @param[in] StdHeader Handle of Header for calling lib functions and services.
147 GetLogicalIdOfSocket (
149 OUT CPU_LOGICAL_ID *LogicalId,
150 IN AMD_CONFIG_PARAMS *StdHeader
155 AGESA_STATUS AssumedSuccess;
159 if (GetPciAddress (StdHeader, (UINT8)Socket, 0, &PciAddress, &AssumedSuccess)) {
160 PciAddress.Address.Function = FUNC_3;
161 PciAddress.Address.Register = CPUID_FMR;
162 LibAmdPciRead (AccessWidth32, PciAddress, &RawCpuid, StdHeader);
163 GetLogicalIdFromCpuid (RawCpuid, LogicalId, StdHeader);
165 LogicalId->Family = 0;
166 LogicalId->Revision = 0;
167 // Logical ID was not found.
173 /*---------------------------------------------------------------------------------------*/
176 * Returns the logical ID of the executing core. This will be obtained by reading
177 * the CPUID and converting it into a "logical ID" which is not package dependent.
179 * @param[out] LogicalId The Processor's Logical ID
180 * @param[in] StdHeader Handle of Header for calling lib functions and services.
184 GetLogicalIdOfCurrentCore (
185 OUT CPU_LOGICAL_ID *LogicalId,
186 IN AMD_CONFIG_PARAMS *StdHeader
189 CPUID_DATA CpuidDataStruct;
191 LibAmdCpuidRead (AMD_CPUID_APICID_LPC_BID, &CpuidDataStruct, StdHeader);
192 GetLogicalIdFromCpuid (CpuidDataStruct.EAX_Reg, LogicalId, StdHeader);
196 /*---------------------------------------------------------------------------------------*/
199 * Returns the logical ID of a processor with the given CPUID value. This
200 * will be obtained by converting it into a "logical ID" which is not package
203 * @param[in] RawCpuid The unprocessed CPUID value to be translated
204 * @param[out] LogicalId The Processor's Logical ID
205 * @param[in] StdHeader Handle of Header for calling lib functions and services
209 GetLogicalIdFromCpuid (
211 OUT CPU_LOGICAL_ID *LogicalId,
212 IN AMD_CONFIG_PARAMS *StdHeader
217 UINT8 NumberOfFamiliesSupported;
218 UINT8 NumberOfLogicalSubFamilies;
219 UINT8 LogicalIdEntries;
222 UINT32 CpuModelAndExtendedModel;
223 UINT64 LogicalFamily;
225 BOOLEAN FamilyNotFound;
226 CONST PF_CPU_GET_SUBFAMILY_ID_ARRAY *SubFamilyIdPtr;
227 CPU_LOGICAL_ID_XLAT *CpuLogicalIdAndRevPtr;
228 CONST CPU_LOGICAL_ID_FAMILY_XLAT *ImageSupportedId;
231 FamilyNotFound = TRUE;
232 CpuLogicalIdAndRevPtr = NULL;
233 ImageSupportedId = CpuSupportedFamilyIdTable.FamilyIdTable;
234 NumberOfFamiliesSupported = CpuSupportedFamilyIdTable.Elements;
236 RawFamily = ((RawCpuid & 0xF00) >> 8) + ((RawCpuid & 0xFF00000) >> 20);
237 RawCpuid &= (UINT32) CPU_FMS_MASK;
238 CpuModelAndExtendedModel = (UINT16) ((RawCpuid >> 8) | RawCpuid);
240 LogicalId->Family = 0;
241 LogicalId->Revision = 0;
243 for (i = 0; i < NumberOfFamiliesSupported && FamilyNotFound; i++) {
244 if (ImageSupportedId[i].Family == RawFamily) {
245 FamilyNotFound = FALSE;
246 LogicalId->Family = ImageSupportedId[i].UnknownRevision.Family;
247 LogicalId->Revision = ImageSupportedId[i].UnknownRevision.Revision;
249 NumberOfLogicalSubFamilies = ImageSupportedId[i].Elements;
250 SubFamilyIdPtr = ImageSupportedId[i].SubFamilyIdTable;
251 for (j = 0; j < NumberOfLogicalSubFamilies && IdNotFound; j++) {
252 SubFamilyIdPtr[j] ((const CPU_LOGICAL_ID_XLAT **)&CpuLogicalIdAndRevPtr, &LogicalIdEntries, &LogicalFamily, StdHeader);
253 ASSERT (CpuLogicalIdAndRevPtr != NULL);
254 for (k = 0; k < LogicalIdEntries; k++) {
255 if (CpuLogicalIdAndRevPtr[k].RawId == CpuModelAndExtendedModel) {
257 LogicalId->Family = LogicalFamily;
258 LogicalId->Revision = CpuLogicalIdAndRevPtr[k].LogicalId;
268 /*---------------------------------------------------------------------------------------*/
271 * Retrieves a pointer to the desired processor's family specific services structure.
273 * @param[in] Socket The Processor in this Socket.
274 * @param[out] FunctionTable The Processor's Family Specific services.
275 * @param[in] StdHeader Handle of Header for calling lib functions and services.
279 GetCpuServicesOfSocket (
281 OUT CONST CPU_SPECIFIC_SERVICES **FunctionTable,
282 IN AMD_CONFIG_PARAMS *StdHeader
285 GetFeatureServicesOfSocket (&CpuSupportedFamiliesTable,
287 (const VOID **)FunctionTable,
289 if (*FunctionTable == NULL) {
290 *FunctionTable = &cpuNullServices;
295 /*---------------------------------------------------------------------------------------*/
298 * Retrieves a pointer to the desired processor's family specific services structure.
300 * @param[in] FamilyTable The table to search in.
301 * @param[in] Socket The Processor in this Socket.
302 * @param[out] CpuServices The Processor's Family Specific services.
303 * @param[in] StdHeader Handle of Header for calling lib functions and services.
307 GetFeatureServicesOfSocket (
308 IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
310 OUT CONST VOID **CpuServices,
311 IN AMD_CONFIG_PARAMS *StdHeader
314 CPU_LOGICAL_ID CpuFamilyRevision;
316 GetLogicalIdOfSocket (Socket, &CpuFamilyRevision, StdHeader);
317 GetFeatureServicesFromLogicalId (FamilyTable, &CpuFamilyRevision, CpuServices, StdHeader);
321 /*---------------------------------------------------------------------------------------*/
324 * Retrieves a pointer to the executing core's family specific services structure.
326 * @param[out] FunctionTable The Processor's Family Specific services.
327 * @param[in] StdHeader Handle of Header for calling lib functions and services.
331 GetCpuServicesOfCurrentCore (
332 OUT CONST CPU_SPECIFIC_SERVICES **FunctionTable,
333 IN AMD_CONFIG_PARAMS *StdHeader
336 GetFeatureServicesOfCurrentCore (&CpuSupportedFamiliesTable,
337 (const VOID **)FunctionTable,
339 if (*FunctionTable == NULL) {
340 *FunctionTable = &cpuNullServices;
344 /*---------------------------------------------------------------------------------------*/
347 * Retrieves a pointer to the family specific services structure for a processor
348 * with the given logical ID.
350 * @param[in] FamilyTable The table to search in.
351 * @param[out] CpuServices The Processor's Family Specific services.
352 * @param[in] StdHeader Handle of Header for calling lib functions and services.
356 GetFeatureServicesOfCurrentCore (
357 IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
358 OUT CONST VOID **CpuServices,
359 IN AMD_CONFIG_PARAMS *StdHeader
362 CPU_LOGICAL_ID CpuFamilyRevision;
364 GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader);
365 GetFeatureServicesFromLogicalId (FamilyTable, &CpuFamilyRevision, CpuServices, StdHeader);
369 /*---------------------------------------------------------------------------------------*/
372 * Retrieves a pointer to the family specific services structure for a processor
373 * with the given logical ID.
375 * @param[in] LogicalId The Processor's logical ID.
376 * @param[out] FunctionTable The Processor's Family Specific services.
377 * @param[in] StdHeader Handle of Header for calling lib functions and services.
381 GetCpuServicesFromLogicalId (
382 IN CPU_LOGICAL_ID *LogicalId,
383 OUT CONST CPU_SPECIFIC_SERVICES **FunctionTable,
384 IN AMD_CONFIG_PARAMS *StdHeader
387 GetFeatureServicesFromLogicalId (&CpuSupportedFamiliesTable,
389 (const VOID **)FunctionTable,
391 if (*FunctionTable == NULL) {
392 *FunctionTable = &cpuNullServices;
396 /*---------------------------------------------------------------------------------------*/
399 * Retrieves a pointer to the family specific services structure for a processor
400 * with the given logical ID.
402 * @param[in] FamilyTable The table to search in.
403 * @param[in] LogicalId The Processor's logical ID.
404 * @param[out] CpuServices The Processor's Family Specific services.
405 * @param[in] StdHeader Handle of Header for calling lib functions and services.
409 GetFeatureServicesFromLogicalId (
410 IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
411 IN CPU_LOGICAL_ID *LogicalId,
412 OUT CONST VOID **CpuServices,
413 IN AMD_CONFIG_PARAMS *StdHeader
416 GetCpuServices (FamilyTable, &LogicalId->Family, CpuServices, StdHeader);
420 /*---------------------------------------------------------------------------------------*/
423 * Finds a family match in the given table, and returns the pointer to the
424 * appropriate table. If no match is found in the table, NULL will be returned.
426 * @param[in] FamilyTable The table to search in.
427 * @param[in] MatchData Family data that must match.
428 * @param[out] CpuServices The Processor's Family Specific services.
429 * @param[in] StdHeader Handle of Header for calling lib functions and services.
435 IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable,
436 IN UINT64 *MatchData,
437 OUT CONST VOID **CpuServices,
438 IN AMD_CONFIG_PARAMS *StdHeader
443 UINT8 NumberOfFamiliesSupported;
444 CONST CPU_SPECIFIC_SERVICES_XLAT *ImageSupportedFamiliesPtr;
446 ImageSupportedFamiliesPtr = FamilyTable->FamilyTable;
447 NumberOfFamiliesSupported = FamilyTable->Elements;
449 for (i = 0; i < NumberOfFamiliesSupported; i++) {
450 if ((ImageSupportedFamiliesPtr[i].Family & *MatchData) != 0) {
456 *CpuServices = ImageSupportedFamiliesPtr[i].TablePtr;
463 /*---------------------------------------------------------------------------------------*/
465 * Used to stub out various family specific tables of information.
467 * @param[in] FamilySpecificServices The current Family Specific Services.
468 * @param[in] Empty NULL, to indicate no data.
469 * @param[out] NumberOfElements Zero, to indicate no data.
470 * @param[in] StdHeader Handle of Header for calling lib functions and services.
475 IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
476 OUT CONST VOID **Empty,
477 OUT UINT8 *NumberOfElements,
478 IN AMD_CONFIG_PARAMS *StdHeader
481 *NumberOfElements = 0;